diff options
author | lj1412 <lji@research.att.com> | 2017-02-14 15:11:54 +0000 |
---|---|---|
committer | lj1412 <lji@research.att.com> | 2017-02-14 15:11:56 +0000 |
commit | 8003361c89f8f497f1f2b327c652487f03b86267 (patch) | |
tree | 5fc8b05ecb2e721a0b00c380b946a9bb661f6c60 /ncomp-utils-java/src | |
parent | 5cf23c1465091439bb06cb78384b1dc2597a6f5e (diff) |
Init ncomp.utils
Change-Id: Ib092dff1d165296e2d86265137cf0b5ae8b20323
Signed-off-by: lj1412 <lji@research.att.com>
Diffstat (limited to 'ncomp-utils-java/src')
89 files changed, 19831 insertions, 0 deletions
diff --git a/ncomp-utils-java/src/main/java/org/json/CDL.java b/ncomp-utils-java/src/main/java/org/json/CDL.java new file mode 100644 index 0000000..563de13 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/CDL.java @@ -0,0 +1,298 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * This provides static methods to convert comma delimited text into a + * JSONArray, and to covert a JSONArray into comma delimited text. Comma + * delimited text is a very popular format for data interchange. It is + * understood by most database, spreadsheet, and organizer programs. + * <p> + * Each row of text represents a row in a table or a data record. Each row + * ends with a NEWLINE character. Each row contains one or more values. + * Values are separated by commas. A value can contain any character except + * for comma, unless is is wrapped in single quotes or double quotes. + * <p> + * The first row usually contains the names of the columns. + * <p> + * A comma delimited list can be converted into a JSONArray of JSONObjects. + * The names for the elements in the JSONObjects can be taken from the names + * in the first row. + * @author JSON.org + * @version 2009-06-18 + */ +public class CDL { + + /** + * Get the next value. The value can be wrapped in quotes. The value can + * be empty. + * @param x A JSONTokener of the source text. + * @return The value string, or null if empty. + * @throws JSONException if the quoted string is badly formed. + */ + private static String getValue(JSONTokener x) throws JSONException { + char c; + char q; + StringBuffer sb; + do { + c = x.next(); + } while (c == ' ' || c == '\t'); + switch (c) { + case 0: + return null; + case '"': + case '\'': + q = c; + sb = new StringBuffer(); + for (;;) { + c = x.next(); + if (c == q) { + break; + } + if (c == 0 || c == '\n' || c == '\r') { + throw x.syntaxError("Missing close quote '" + q + "'."); + } + sb.append(c); + } + return sb.toString(); + case ',': + x.back(); + return ""; + default: + x.back(); + return x.nextTo(','); + } + } + + /** + * Produce a JSONArray of strings from a row of comma delimited values. + * @param x A JSONTokener of the source text. + * @return A JSONArray of strings. + * @throws JSONException + */ + public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { + JSONArray ja = new JSONArray(); + for (;;) { + String value = getValue(x); + if (value == null || (ja.length() == 0 && value.length() == 0)) { + return null; + } + ja.put(value); + for (;;) { + char c = x.next(); + if (c == ',') { + break; + } + if (c != ' ') { + if (c == '\n' || c == '\r' || c == 0) { + return ja; + } + throw x.syntaxError("Bad character '" + c + "' (" + + (int)c + ")."); + } + } + } + } + + /** + * Produce a JSONObject from a row of comma delimited text, using a + * parallel JSONArray of strings to provides the names of the elements. + * @param names A JSONArray of names. This is commonly obtained from the + * first row of a comma delimited text file using the rowToJSONArray + * method. + * @param x A JSONTokener of the source text. + * @return A JSONObject combining the names and values. + * @throws JSONException + */ + public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) + throws JSONException { + JSONArray ja = rowToJSONArray(x); + return ja != null ? ja.toJSONObject(names) : null; + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string, + * using the first row as a source of names. + * @param string The comma delimited text. + * @return A JSONArray of JSONObjects. + * @throws JSONException + */ + public static JSONArray toJSONArray(String string) throws JSONException { + return toJSONArray(new JSONTokener(string)); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string, + * using the first row as a source of names. + * @param x The JSONTokener containing the comma delimited text. + * @return A JSONArray of JSONObjects. + * @throws JSONException + */ + public static JSONArray toJSONArray(JSONTokener x) throws JSONException { + return toJSONArray(rowToJSONArray(x), x); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string + * using a supplied JSONArray as the source of element names. + * @param names A JSONArray of strings. + * @param string The comma delimited text. + * @return A JSONArray of JSONObjects. + * @throws JSONException + */ + public static JSONArray toJSONArray(JSONArray names, String string) + throws JSONException { + return toJSONArray(names, new JSONTokener(string)); + } + + /** + * Produce a JSONArray of JSONObjects from a comma delimited text string + * using a supplied JSONArray as the source of element names. + * @param names A JSONArray of strings. + * @param x A JSONTokener of the source text. + * @return A JSONArray of JSONObjects. + * @throws JSONException + */ + public static JSONArray toJSONArray(JSONArray names, JSONTokener x) + throws JSONException { + if (names == null || names.length() == 0) { + return null; + } + JSONArray ja = new JSONArray(); + for (;;) { + JSONObject jo = rowToJSONObject(names, x); + if (jo == null) { + break; + } + ja.put(jo); + } + if (ja.length() == 0) { + return null; + } + return ja; + } + + + /** + * Produce a comma delimited text row from a JSONArray. Values containing + * the comma character will be quoted. Troublesome characters may be + * removed. + * @param ja A JSONArray of strings. + * @return A string ending in NEWLINE. + */ + public static String rowToString(JSONArray ja) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < ja.length(); i += 1) { + if (i > 0) { + sb.append(','); + } + Object o = ja.opt(i); + if (o != null) { + String s = o.toString(); + if (s.indexOf(',') >= 0 || s.indexOf('\n') >= 0 || + s.indexOf('\r') >= 0 || s.indexOf(0) >= 0 || + s.charAt(0) == '"') { + sb.append('"'); + int length = s.length(); + for (int j = 0; j < length; j += 1) { + char c = s.charAt(j); + if (c >= ' ' && c != '"') { + sb.append(c); + } + } + sb.append('"'); + } else { + sb.append(s); + } + } + } + sb.append('\n'); + return sb.toString(); + } + + /** + * Produce a comma delimited text from a JSONArray of JSONObjects. The + * first row will be a list of names obtained by inspecting the first + * JSONObject. + * @param ja A JSONArray of JSONObjects. + * @return A comma delimited text. + * @throws JSONException + */ + public static String toString(JSONArray ja) throws JSONException { + JSONObject jo = ja.optJSONObject(0); + if (jo != null) { + JSONArray names = jo.names(); + if (names != null) { + return rowToString(names) + toString(names, ja); + } + } + return null; + } + + /** + * Produce a comma delimited text from a JSONArray of JSONObjects using + * a provided list of names. The list of names is not included in the + * output. + * @param names A JSONArray of strings. + * @param ja A JSONArray of JSONObjects. + * @return A comma delimited text. + * @throws JSONException + */ + public static String toString(JSONArray names, JSONArray ja) + throws JSONException { + if (names == null || names.length() == 0) { + return null; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < ja.length(); i += 1) { + JSONObject jo = ja.optJSONObject(i); + if (jo != null) { + sb.append(rowToString(jo.toJSONArray(names))); + } + } + return sb.toString(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/Cookie.java b/ncomp-utils-java/src/main/java/org/json/Cookie.java new file mode 100644 index 0000000..cf8746b --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/Cookie.java @@ -0,0 +1,190 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * Convert a web browser cookie specification to a JSONObject and back. + * JSON and Cookies are both notations for name/value pairs. + * @author JSON.org + * @version 2008-09-18 + */ +public class Cookie { + + /** + * Produce a copy of a string in which the characters '+', '%', '=', ';' + * and control characters are replaced with "%hh". This is a gentle form + * of URL encoding, attempting to cause as little distortion to the + * string as possible. The characters '=' and ';' are meta characters in + * cookies. By convention, they are escaped using the URL-encoding. This is + * only a convention, not a standard. Often, cookies are expected to have + * encoded values. We encode '=' and ';' because we must. We encode '%' and + * '+' because they are meta characters in URL encoding. + * @param string The source string. + * @return The escaped result. + */ + public static String escape(String string) { + char c; + String s = string.trim(); + StringBuffer sb = new StringBuffer(); + int len = s.length(); + for (int i = 0; i < len; i += 1) { + c = s.charAt(i); + if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') { + sb.append('%'); + sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16)); + sb.append(Character.forDigit((char)(c & 0x0f), 16)); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + + /** + * Convert a cookie specification string into a JSONObject. The string + * will contain a name value pair separated by '='. The name and the value + * will be unescaped, possibly converting '+' and '%' sequences. The + * cookie properties may follow, separated by ';', also represented as + * name=value (except the secure property, which does not have a value). + * The name will be stored under the key "name", and the value will be + * stored under the key "value". This method does not do checking or + * validation of the parameters. It only converts the cookie string into + * a JSONObject. + * @param string The cookie specification string. + * @return A JSONObject containing "name", "value", and possibly other + * members. + * @throws JSONException + */ + public static JSONObject toJSONObject(String string) throws JSONException { + String n; + JSONObject o = new JSONObject(); + Object v; + JSONTokener x = new JSONTokener(string); + o.put("name", x.nextTo('=')); + x.next('='); + o.put("value", x.nextTo(';')); + x.next(); + while (x.more()) { + n = unescape(x.nextTo("=;")); + if (x.next() != '=') { + if (n.equals("secure")) { + v = Boolean.TRUE; + } else { + throw x.syntaxError("Missing '=' in cookie parameter."); + } + } else { + v = unescape(x.nextTo(';')); + x.next(); + } + o.put(n, v); + } + return o; + } + + + /** + * Convert a JSONObject into a cookie specification string. The JSONObject + * must contain "name" and "value" members. + * If the JSONObject contains "expires", "domain", "path", or "secure" + * members, they will be appended to the cookie specification string. + * All other members are ignored. + * @param o A JSONObject + * @return A cookie specification string + * @throws JSONException + */ + public static String toString(JSONObject o) throws JSONException { + StringBuffer sb = new StringBuffer(); + + sb.append(escape(o.getString("name"))); + sb.append("="); + sb.append(escape(o.getString("value"))); + if (o.has("expires")) { + sb.append(";expires="); + sb.append(o.getString("expires")); + } + if (o.has("domain")) { + sb.append(";domain="); + sb.append(escape(o.getString("domain"))); + } + if (o.has("path")) { + sb.append(";path="); + sb.append(escape(o.getString("path"))); + } + if (o.optBoolean("secure")) { + sb.append(";secure"); + } + return sb.toString(); + } + + /** + * Convert <code>%</code><i>hh</i> sequences to single characters, and + * convert plus to space. + * @param s A string that may contain + * <code>+</code> <small>(plus)</small> and + * <code>%</code><i>hh</i> sequences. + * @return The unescaped string. + */ + public static String unescape(String s) { + int len = s.length(); + StringBuffer b = new StringBuffer(); + for (int i = 0; i < len; ++i) { + char c = s.charAt(i); + if (c == '+') { + c = ' '; + } else if (c == '%' && i + 2 < len) { + int d = JSONTokener.dehexchar(s.charAt(i + 1)); + int e = JSONTokener.dehexchar(s.charAt(i + 2)); + if (d >= 0 && e >= 0) { + c = (char)(d * 16 + e); + i += 2; + } + } + b.append(c); + } + return b.toString(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/CookieList.java b/ncomp-utils-java/src/main/java/org/json/CookieList.java new file mode 100644 index 0000000..06b01ef --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/CookieList.java @@ -0,0 +1,111 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Iterator; + +/** + * Convert a web browser cookie list string to a JSONObject and back. + * @author JSON.org + * @version 2008-09-18 + */ +public class CookieList { + + /** + * Convert a cookie list into a JSONObject. A cookie list is a sequence + * of name/value pairs. The names are separated from the values by '='. + * The pairs are separated by ';'. The names and the values + * will be unescaped, possibly converting '+' and '%' sequences. + * + * To add a cookie to a cooklist, + * cookielistJSONObject.put(cookieJSONObject.getString("name"), + * cookieJSONObject.getString("value")); + * @param string A cookie list string + * @return A JSONObject + * @throws JSONException + */ + public static JSONObject toJSONObject(String string) throws JSONException { + JSONObject o = new JSONObject(); + JSONTokener x = new JSONTokener(string); + while (x.more()) { + String name = Cookie.unescape(x.nextTo('=')); + x.next('='); + o.put(name, Cookie.unescape(x.nextTo(';'))); + x.next(); + } + return o; + } + + + /** + * Convert a JSONObject into a cookie list. A cookie list is a sequence + * of name/value pairs. The names are separated from the values by '='. + * The pairs are separated by ';'. The characters '%', '+', '=', and ';' + * in the names and values are replaced by "%hh". + * @param o A JSONObject + * @return A cookie list string + * @throws JSONException + */ + public static String toString(JSONObject o) throws JSONException { + boolean b = false; + Iterator<String> keys = o.keys(); + String s; + StringBuffer sb = new StringBuffer(); + while (keys.hasNext()) { + s = keys.next().toString(); + if (!o.isNull(s)) { + if (b) { + sb.append(';'); + } + sb.append(Cookie.escape(s)); + sb.append("="); + sb.append(Cookie.escape(o.getString(s))); + b = true; + } + } + return sb.toString(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/HTTP.java b/ncomp-utils-java/src/main/java/org/json/HTTP.java new file mode 100644 index 0000000..ef37d2d --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/HTTP.java @@ -0,0 +1,184 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Iterator; + +/** + * Convert an HTTP header to a JSONObject and back. + * @author JSON.org + * @version 2008-09-18 + */ +public class HTTP { + + /** Carriage return/line feed. */ + public static final String CRLF = "\r\n"; + + /** + * Convert an HTTP header string into a JSONObject. It can be a request + * header or a response header. A request header will contain + * <pre>{ + * Method: "POST" (for example), + * "Request-URI": "/" (for example), + * "HTTP-Version": "HTTP/1.1" (for example) + * }</pre> + * A response header will contain + * <pre>{ + * "HTTP-Version": "HTTP/1.1" (for example), + * "Status-Code": "200" (for example), + * "Reason-Phrase": "OK" (for example) + * }</pre> + * In addition, the other parameters in the header will be captured, using + * the HTTP field names as JSON names, so that <pre> + * Date: Sun, 26 May 2002 18:06:04 GMT + * Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s + * Cache-Control: no-cache</pre> + * become + * <pre>{... + * Date: "Sun, 26 May 2002 18:06:04 GMT", + * Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s", + * "Cache-Control": "no-cache", + * ...}</pre> + * It does no further checking or conversion. It does not parse dates. + * It does not do '%' transforms on URLs. + * @param string An HTTP header string. + * @return A JSONObject containing the elements and attributes + * of the XML string. + * @throws JSONException + */ + public static JSONObject toJSONObject(String string) throws JSONException { + JSONObject o = new JSONObject(); + HTTPTokener x = new HTTPTokener(string); + String t; + + t = x.nextToken(); + if (t.toUpperCase().startsWith("HTTP")) { + +// Response + + o.put("HTTP-Version", t); + o.put("Status-Code", x.nextToken()); + o.put("Reason-Phrase", x.nextTo('\0')); + x.next(); + + } else { + +// Request + + o.put("Method", t); + o.put("Request-URI", x.nextToken()); + o.put("HTTP-Version", x.nextToken()); + } + +// Fields + + while (x.more()) { + String name = x.nextTo(':'); + x.next(':'); + o.put(name, x.nextTo('\0')); + x.next(); + } + return o; + } + + + /** + * Convert a JSONObject into an HTTP header. A request header must contain + * <pre>{ + * Method: "POST" (for example), + * "Request-URI": "/" (for example), + * "HTTP-Version": "HTTP/1.1" (for example) + * }</pre> + * A response header must contain + * <pre>{ + * "HTTP-Version": "HTTP/1.1" (for example), + * "Status-Code": "200" (for example), + * "Reason-Phrase": "OK" (for example) + * }</pre> + * Any other members of the JSONObject will be output as HTTP fields. + * The result will end with two CRLF pairs. + * @param o A JSONObject + * @return An HTTP header string. + * @throws JSONException if the object does not contain enough + * information. + */ + public static String toString(JSONObject o) throws JSONException { + Iterator<String> keys = o.keys(); + String s; + StringBuffer sb = new StringBuffer(); + if (o.has("Status-Code") && o.has("Reason-Phrase")) { + sb.append(o.getString("HTTP-Version")); + sb.append(' '); + sb.append(o.getString("Status-Code")); + sb.append(' '); + sb.append(o.getString("Reason-Phrase")); + } else if (o.has("Method") && o.has("Request-URI")) { + sb.append(o.getString("Method")); + sb.append(' '); + sb.append('"'); + sb.append(o.getString("Request-URI")); + sb.append('"'); + sb.append(' '); + sb.append(o.getString("HTTP-Version")); + } else { + throw new JSONException("Not enough material for an HTTP header."); + } + sb.append(CRLF); + while (keys.hasNext()) { + s = keys.next().toString(); + if (!s.equals("HTTP-Version") && !s.equals("Status-Code") && + !s.equals("Reason-Phrase") && !s.equals("Method") && + !s.equals("Request-URI") && !o.isNull(s)) { + sb.append(s); + sb.append(": "); + sb.append(o.getString(s)); + sb.append(CRLF); + } + } + sb.append(CRLF); + return sb.toString(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/HTTPTokener.java b/ncomp-utils-java/src/main/java/org/json/HTTPTokener.java new file mode 100644 index 0000000..39c003e --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/HTTPTokener.java @@ -0,0 +1,98 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * The HTTPTokener extends the JSONTokener to provide additional methods + * for the parsing of HTTP headers. + * @author JSON.org + * @version 2008-09-18 + */ +public class HTTPTokener extends JSONTokener { + + /** + * Construct an HTTPTokener from a string. + * @param s A source string. + */ + public HTTPTokener(String s) { + super(s); + } + + + /** + * Get the next token or string. This is used in parsing HTTP headers. + * @throws JSONException + * @return A String. + */ + public String nextToken() throws JSONException { + char c; + char q; + StringBuffer sb = new StringBuffer(); + do { + c = next(); + } while (Character.isWhitespace(c)); + if (c == '"' || c == '\'') { + q = c; + for (;;) { + c = next(); + if (c < ' ') { + throw syntaxError("Unterminated string."); + } + if (c == q) { + return sb.toString(); + } + sb.append(c); + } + } + for (;;) { + if (c == 0 || Character.isWhitespace(c)) { + return sb.toString(); + } + sb.append(c); + c = next(); + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/JSONArray.java b/ncomp-utils-java/src/main/java/org/json/JSONArray.java new file mode 100644 index 0000000..2205ea1 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONArray.java @@ -0,0 +1,982 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +/** + * A JSONArray is an ordered sequence of values. Its external text form is a + * string wrapped in square brackets with commas separating the values. The + * internal form is an object having <code>get</code> and <code>opt</code> + * methods for accessing the values by index, and <code>put</code> methods for + * adding or replacing values. The values can be any of these types: + * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, + * <code>Number</code>, <code>String</code>, or the + * <code>JSONObject.NULL object</code>. + * <p> + * The constructor can convert a JSON text into a Java object. The + * <code>toString</code> method converts to JSON text. + * <p> + * A <code>get</code> method returns a value if one can be found, and throws an + * exception if one cannot be found. An <code>opt</code> method returns a + * default value instead of throwing an exception, and so is useful for + * obtaining optional values. + * <p> + * The generic <code>get()</code> and <code>opt()</code> methods return an + * object which you can cast or query for type. There are also typed + * <code>get</code> and <code>opt</code> methods that do type checking and type + * coercion for you. + * <p> + * The texts produced by the <code>toString</code> methods strictly conform to + * JSON syntax rules. The constructors are more forgiving in the texts they will + * accept: + * <ul> + * <li>An extra <code>,</code> <small>(comma)</small> may appear just + * before the closing bracket.</li> + * <li>The <code>null</code> value will be inserted when there + * is <code>,</code> <small>(comma)</small> elision.</li> + * <li>Strings may be quoted with <code>'</code> <small>(single + * quote)</small>.</li> + * <li>Strings do not need to be quoted at all if they do not begin with a quote + * or single quote, and if they do not contain leading or trailing spaces, + * and if they do not contain any of these characters: + * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers + * and if they are not the reserved words <code>true</code>, + * <code>false</code>, or <code>null</code>.</li> + * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as + * well as by <code>,</code> <small>(comma)</small>.</li> + * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or + * <code>0x-</code> <small>(hex)</small> prefix.</li> + * </ul> + + * @author JSON.org + * @version 2009-04-13 + */ +public class JSONArray { + + + /** + * The arrayList where the JSONArray's properties are kept. + */ + private ArrayList<Object> myArrayList; + + + /** + * Construct an empty JSONArray. + */ + public JSONArray() { + this.myArrayList = new ArrayList<Object>(); + } + + /** + * Construct a JSONArray from a JSONTokener. + * @param x A JSONTokener + * @throws JSONException If there is a syntax error. + */ + public JSONArray(JSONTokener x) throws JSONException { + this(); + char c = x.nextClean(); + char q; + if (c == '[') { + q = ']'; + } else if (c == '(') { + q = ')'; + } else { + throw x.syntaxError("A JSONArray text must start with '['"); + } + if (x.nextClean() == ']') { + return; + } + x.back(); + for (;;) { + if (x.nextClean() == ',') { + x.back(); + this.myArrayList.add(null); + } else { + x.back(); + this.myArrayList.add(x.nextValue()); + } + c = x.nextClean(); + switch (c) { + case ';': + case ',': + if (x.nextClean() == ']') { + return; + } + x.back(); + break; + case ']': + case ')': + if (q != c) { + throw x.syntaxError("Expected a '" + new Character(q) + "'"); + } + return; + default: + throw x.syntaxError("Expected a ',' or ']'"); + } + } + } + + + /** + * Construct a JSONArray from a source JSON text. + * @param source A string that begins with + * <code>[</code> <small>(left bracket)</small> + * and ends with <code>]</code> <small>(right bracket)</small>. + * @throws JSONException If there is a syntax error. + */ + public JSONArray(String source) throws JSONException { + this(new JSONTokener(source)); + } + + + /** + * Construct a JSONArray from a Collection. + * @param collection A Collection. + */ + public JSONArray(Collection<?> collection) { + this.myArrayList = (collection == null) ? + new ArrayList<Object>() : + new ArrayList<Object>(collection); + } + + /** + * Construct a JSONArray from a collection of beans. + * The collection should have Java Beans. + * + * @throws JSONException If not an array. + */ + + public JSONArray(Collection<?> collection, boolean includeSuperClass) { + this.myArrayList = new ArrayList<Object>(); + if (collection != null) { + Iterator<?> iter = collection.iterator();; + while (iter.hasNext()) { + Object o = iter.next(); + if (o instanceof Map) { + this.myArrayList.add(new JSONObject((Map<?, ?>)o, includeSuperClass)); + } else if (!JSONObject.isStandardProperty(o.getClass())) { + this.myArrayList.add(new JSONObject(o, includeSuperClass)); + } else { + this.myArrayList.add(o); + } + } + } + } + + + /** + * Construct a JSONArray from an array + * @throws JSONException If not an array. + */ + public JSONArray(Object array) throws JSONException { + this(); + if (array.getClass().isArray()) { + int length = Array.getLength(array); + for (int i = 0; i < length; i += 1) { + this.put(Array.get(array, i)); + } + } else { + throw new JSONException("JSONArray initial value should be a string or collection or array."); + } + } + + /** + * Construct a JSONArray from an array with a bean. + * The array should have Java Beans. + * + * @throws JSONException If not an array. + */ + public JSONArray(Object array,boolean includeSuperClass) throws JSONException { + this(); + if (array.getClass().isArray()) { + int length = Array.getLength(array); + for (int i = 0; i < length; i += 1) { + Object o = Array.get(array, i); + if (JSONObject.isStandardProperty(o.getClass())) { + this.myArrayList.add(o); + } else { + this.myArrayList.add(new JSONObject(o,includeSuperClass)); + } + } + } else { + throw new JSONException("JSONArray initial value should be a string or collection or array."); + } + } + + + + /** + * Get the object value associated with an index. + * @param index + * The index must be between 0 and length() - 1. + * @return An object value. + * @throws JSONException If there is no value for the index. + */ + public Object get(int index) throws JSONException { + Object o = opt(index); + if (o == null) { + throw new JSONException("JSONArray[" + index + "] not found."); + } + return o; + } + + + /** + * Get the boolean value associated with an index. + * The string values "true" and "false" are converted to boolean. + * + * @param index The index must be between 0 and length() - 1. + * @return The truth. + * @throws JSONException If there is no value for the index or if the + * value is not convertable to boolean. + */ + public boolean getBoolean(int index) throws JSONException { + Object o = get(index); + if (o.equals(Boolean.FALSE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("false"))) { + return false; + } else if (o.equals(Boolean.TRUE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("true"))) { + return true; + } + throw new JSONException("JSONArray[" + index + "] is not a Boolean."); + } + + + /** + * Get the double value associated with an index. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException If the key is not found or if the value cannot + * be converted to a number. + */ + public double getDouble(int index) throws JSONException { + Object o = get(index); + try { + return o instanceof Number ? + ((Number)o).doubleValue() : + Double.valueOf((String)o).doubleValue(); + } catch (Exception e) { + throw new JSONException("JSONArray[" + index + + "] is not a number."); + } + } + + + /** + * Get the int value associated with an index. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException If the key is not found or if the value cannot + * be converted to a number. + * if the value cannot be converted to a number. + */ + public int getInt(int index) throws JSONException { + Object o = get(index); + return o instanceof Number ? + ((Number)o).intValue() : (int)getDouble(index); + } + + + /** + * Get the JSONArray associated with an index. + * @param index The index must be between 0 and length() - 1. + * @return A JSONArray value. + * @throws JSONException If there is no value for the index. or if the + * value is not a JSONArray + */ + public JSONArray getJSONArray(int index) throws JSONException { + Object o = get(index); + if (o instanceof JSONArray) { + return (JSONArray)o; + } + throw new JSONException("JSONArray[" + index + + "] is not a JSONArray."); + } + + + /** + * Get the JSONObject associated with an index. + * @param index subscript + * @return A JSONObject value. + * @throws JSONException If there is no value for the index or if the + * value is not a JSONObject + */ + public JSONObject getJSONObject(int index) throws JSONException { + Object o = get(index); + if (o instanceof JSONObject) { + return (JSONObject)o; + } + throw new JSONException("JSONArray[" + index + + "] is not a JSONObject."); + } + + + /** + * Get the long value associated with an index. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException If the key is not found or if the value cannot + * be converted to a number. + */ + public long getLong(int index) throws JSONException { + Object o = get(index); + return o instanceof Number ? + ((Number)o).longValue() : (long)getDouble(index); + } + + + /** + * Get the string associated with an index. + * @param index The index must be between 0 and length() - 1. + * @return A string value. + * @throws JSONException If there is no value for the index. + */ + public String getString(int index) throws JSONException { + return get(index).toString(); + } + + + /** + * Determine if the value is null. + * @param index The index must be between 0 and length() - 1. + * @return true if the value at the index is null, or if there is no value. + */ + public boolean isNull(int index) { + return JSONObject.NULL.equals(opt(index)); + } + + + /** + * Make a string from the contents of this JSONArray. The + * <code>separator</code> string is inserted between each element. + * Warning: This method assumes that the data structure is acyclical. + * @param separator A string that will be inserted between the elements. + * @return a string. + * @throws JSONException If the array contains an invalid number. + */ + public String join(String separator) throws JSONException { + int len = length(); + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < len; i += 1) { + if (i > 0) { + sb.append(separator); + } + sb.append(JSONObject.valueToString(this.myArrayList.get(i))); + } + return sb.toString(); + } + + + /** + * Get the number of elements in the JSONArray, included nulls. + * + * @return The length (or size). + */ + public int length() { + return this.myArrayList.size(); + } + + + /** + * Get the optional object value associated with an index. + * @param index The index must be between 0 and length() - 1. + * @return An object value, or null if there is no + * object at that index. + */ + public Object opt(int index) { + return (index < 0 || index >= length()) ? + null : this.myArrayList.get(index); + } + + + /** + * Get the optional boolean value associated with an index. + * It returns false if there is no value at that index, + * or if the value is not Boolean.TRUE or the String "true". + * + * @param index The index must be between 0 and length() - 1. + * @return The truth. + */ + public boolean optBoolean(int index) { + return optBoolean(index, false); + } + + + /** + * Get the optional boolean value associated with an index. + * It returns the defaultValue if there is no value at that index or if + * it is not a Boolean or the String "true" or "false" (case insensitive). + * + * @param index The index must be between 0 and length() - 1. + * @param defaultValue A boolean default. + * @return The truth. + */ + public boolean optBoolean(int index, boolean defaultValue) { + try { + return getBoolean(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional double value associated with an index. + * NaN is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + */ + public double optDouble(int index) { + return optDouble(index, Double.NaN); + } + + + /** + * Get the optional double value associated with an index. + * The defaultValue is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index subscript + * @param defaultValue The default value. + * @return The value. + */ + public double optDouble(int index, double defaultValue) { + try { + return getDouble(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional int value associated with an index. + * Zero is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + */ + public int optInt(int index) { + return optInt(index, 0); + } + + + /** + * Get the optional int value associated with an index. + * The defaultValue is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * @param index The index must be between 0 and length() - 1. + * @param defaultValue The default value. + * @return The value. + */ + public int optInt(int index, int defaultValue) { + try { + return getInt(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional JSONArray associated with an index. + * @param index subscript + * @return A JSONArray value, or null if the index has no value, + * or if the value is not a JSONArray. + */ + public JSONArray optJSONArray(int index) { + Object o = opt(index); + return o instanceof JSONArray ? (JSONArray)o : null; + } + + + /** + * Get the optional JSONObject associated with an index. + * Null is returned if the key is not found, or null if the index has + * no value, or if the value is not a JSONObject. + * + * @param index The index must be between 0 and length() - 1. + * @return A JSONObject value. + */ + public JSONObject optJSONObject(int index) { + Object o = opt(index); + return o instanceof JSONObject ? (JSONObject)o : null; + } + + + /** + * Get the optional long value associated with an index. + * Zero is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + */ + public long optLong(int index) { + return optLong(index, 0); + } + + + /** + * Get the optional long value associated with an index. + * The defaultValue is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * @param index The index must be between 0 and length() - 1. + * @param defaultValue The default value. + * @return The value. + */ + public long optLong(int index, long defaultValue) { + try { + return getLong(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional string value associated with an index. It returns an + * empty string if there is no value at that index. If the value + * is not a string and is not null, then it is coverted to a string. + * + * @param index The index must be between 0 and length() - 1. + * @return A String value. + */ + public String optString(int index) { + return optString(index, ""); + } + + + /** + * Get the optional string associated with an index. + * The defaultValue is returned if the key is not found. + * + * @param index The index must be between 0 and length() - 1. + * @param defaultValue The default value. + * @return A String value. + */ + public String optString(int index, String defaultValue) { + Object o = opt(index); + return o != null ? o.toString() : defaultValue; + } + + + /** + * Append a boolean value. This increases the array's length by one. + * + * @param value A boolean value. + * @return this. + */ + public JSONArray put(boolean value) { + put(value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONArray which is produced from a Collection. + * @param value A Collection value. + * @return this. + */ + public JSONArray put(Collection<?> value) { + put(new JSONArray(value)); + return this; + } + + + /** + * Append a double value. This increases the array's length by one. + * + * @param value A double value. + * @throws JSONException if the value is not finite. + * @return this. + */ + public JSONArray put(double value) throws JSONException { + Double d = new Double(value); + JSONObject.testValidity(d); + put(d); + return this; + } + + + /** + * Append an int value. This increases the array's length by one. + * + * @param value An int value. + * @return this. + */ + public JSONArray put(int value) { + put(new Integer(value)); + return this; + } + + + /** + * Append an long value. This increases the array's length by one. + * + * @param value A long value. + * @return this. + */ + public JSONArray put(long value) { + put(new Long(value)); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONObject which is produced from a Map. + * @param value A Map value. + * @return this. + */ + public JSONArray put(Map<?, ?> value) { + put(new JSONObject(value)); + return this; + } + + + /** + * Append an object value. This increases the array's length by one. + * @param value An object value. The value should be a + * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the + * JSONObject.NULL object. + * @return this. + */ + public JSONArray put(Object value) { + this.myArrayList.add(value); + return this; + } + + + /** + * Put or replace a boolean value in the JSONArray. If the index is greater + * than the length of the JSONArray, then null elements will be added as + * necessary to pad it out. + * @param index The subscript. + * @param value A boolean value. + * @return this. + * @throws JSONException If the index is negative. + */ + public JSONArray put(int index, boolean value) throws JSONException { + put(index, value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONArray which is produced from a Collection. + * @param index The subscript. + * @param value A Collection value. + * @return this. + * @throws JSONException If the index is negative or if the value is + * not finite. + */ + public JSONArray put(int index, Collection<?> value) throws JSONException { + put(index, new JSONArray(value)); + return this; + } + + + /** + * Put or replace a double value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad + * it out. + * @param index The subscript. + * @param value A double value. + * @return this. + * @throws JSONException If the index is negative or if the value is + * not finite. + */ + public JSONArray put(int index, double value) throws JSONException { + put(index, new Double(value)); + return this; + } + + + /** + * Put or replace an int value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad + * it out. + * @param index The subscript. + * @param value An int value. + * @return this. + * @throws JSONException If the index is negative. + */ + public JSONArray put(int index, int value) throws JSONException { + put(index, new Integer(value)); + return this; + } + + + /** + * Put or replace a long value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad + * it out. + * @param index The subscript. + * @param value A long value. + * @return this. + * @throws JSONException If the index is negative. + */ + public JSONArray put(int index, long value) throws JSONException { + put(index, new Long(value)); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONObject which is produced from a Map. + * @param index The subscript. + * @param value The Map value. + * @return this. + * @throws JSONException If the index is negative or if the the value is + * an invalid number. + */ + public JSONArray put(int index, Map<?, ?> value) throws JSONException { + put(index, new JSONObject(value)); + return this; + } + + + /** + * Put or replace an object value in the JSONArray. If the index is greater + * than the length of the JSONArray, then null elements will be added as + * necessary to pad it out. + * @param index The subscript. + * @param value The value to put into the array. The value should be a + * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the + * JSONObject.NULL object. + * @return this. + * @throws JSONException If the index is negative or if the the value is + * an invalid number. + */ + public JSONArray put(int index, Object value) throws JSONException { + JSONObject.testValidity(value); + if (index < 0) { + throw new JSONException("JSONArray[" + index + "] not found."); + } + if (index < length()) { + this.myArrayList.set(index, value); + } else { + while (index != length()) { + put(JSONObject.NULL); + } + put(value); + } + return this; + } + + + /** + * Remove a index and close the hole. + * @param index The index of the element to be removed. + * @return The value that was associated with the index, + * or null if there was no value. + */ + public Object remove(int index) { + Object o = opt(index); + this.myArrayList.remove(index); + return o; + } + + + /** + * Produce a JSONObject by combining a JSONArray of names with the values + * of this JSONArray. + * @param names A JSONArray containing a list of key strings. These will be + * paired with the values. + * @return A JSONObject, or null if there are no names or if this JSONArray + * has no values. + * @throws JSONException If any of the names are null. + */ + public JSONObject toJSONObject(JSONArray names) throws JSONException { + if (names == null || names.length() == 0 || length() == 0) { + return null; + } + JSONObject jo = new JSONObject(); + for (int i = 0; i < names.length(); i += 1) { + jo.put(names.getString(i), this.opt(i)); + } + return jo; + } + + + /** + * Make a JSON text of this JSONArray. For compactness, no + * unnecessary whitespace is added. If it is not possible to produce a + * syntactically correct JSON text then null will be returned instead. This + * could occur if the array contains an invalid number. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * + * @return a printable, displayable, transmittable + * representation of the array. + */ + @Override + public String toString() { + try { + return '[' + join(",") + ']'; + } catch (Exception e) { + return null; + } + } + + + /** + * Make a prettyprinted JSON text of this JSONArray. + * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with <code>[</code> <small>(left bracket)</small> and ending + * with <code>]</code> <small>(right bracket)</small>. + * @throws JSONException + */ + public String toString(int indentFactor) throws JSONException { + return toString(indentFactor, 0); + } + + + /** + * Make a prettyprinted JSON text of this JSONArray. + * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indention of the top level. + * @return a printable, displayable, transmittable + * representation of the array. + * @throws JSONException + */ + String toString(int indentFactor, int indent) throws JSONException { + int len = length(); + if (len == 0) { + return "[]"; + } + int i; + StringBuffer sb = new StringBuffer("["); + if (len == 1) { + sb.append(JSONObject.valueToString(this.myArrayList.get(0), + indentFactor, indent)); + } else { + int newindent = indent + indentFactor; + sb.append('\n'); + for (i = 0; i < len; i += 1) { + if (i > 0) { + sb.append(",\n"); + } + for (int j = 0; j < newindent; j += 1) { + sb.append(' '); + } + sb.append(JSONObject.valueToString(this.myArrayList.get(i), + indentFactor, newindent)); + } + sb.append('\n'); + for (i = 0; i < indent; i += 1) { + sb.append(' '); + } + } + sb.append(']'); + return sb.toString(); + } + + + /** + * Write the contents of the JSONArray as JSON text to a writer. + * For compactness, no whitespace is added. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * + * @return The writer. + * @throws JSONException + */ + public Writer write(Writer writer) throws JSONException { + try { + boolean b = false; + int len = length(); + + writer.write('['); + + for (int i = 0; i < len; i += 1) { + if (b) { + writer.write(','); + } + Object v = this.myArrayList.get(i); + if (v instanceof JSONObject) { + ((JSONObject)v).write(writer); + } else if (v instanceof JSONArray) { + ((JSONArray)v).write(writer); + } else { + writer.write(JSONObject.valueToString(v)); + } + b = true; + } + writer.write(']'); + return writer; + } catch (IOException e) { + throw new JSONException(e); + } + } +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/json/JSONException.java b/ncomp-utils-java/src/main/java/org/json/JSONException.java new file mode 100644 index 0000000..3dbe31f --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONException.java @@ -0,0 +1,51 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/** + * The JSONException is thrown by the JSON.org classes then things are amiss. + * @author JSON.org + * @version 2008-09-18 + */ + +@SuppressWarnings("serial") +public class JSONException extends RuntimeException { + private Throwable cause; + + /** + * Constructs a JSONException with an explanatory message. + * @param message Detail about the reason for the exception. + */ + public JSONException(String message) { + super(message); + } + + public JSONException(Throwable t) { + super(t.getMessage()); + this.cause = t; + } + + @Override + public Throwable getCause() { + return this.cause; + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/JSONML.java b/ncomp-utils-java/src/main/java/org/json/JSONML.java new file mode 100644 index 0000000..4cc818a --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONML.java @@ -0,0 +1,476 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2008 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Iterator; + + +/** + * This provides static methods to convert an XML text into a JSONArray or + * JSONObject, and to covert a JSONArray or JSONObject into an XML text using + * the JsonML transform. + * @author JSON.org + * @version 2008-11-20 + */ +public class JSONML { + + /** + * Parse XML values and store them in a JSONArray. + * @param x The XMLTokener containing the source string. + * @param arrayForm true if array form, false if object form. + * @param ja The JSONArray that is containing the current tag or null + * if we are at the outermost level. + * @return A JSONArray if the value is the outermost tag, otherwise null. + * @throws JSONException + */ + private static Object parse(XMLTokener x, boolean arrayForm, + JSONArray ja) throws JSONException { + String attribute; + char c; + String closeTag = null; + int i; + JSONArray newja = null; + JSONObject newjo = null; + Object token; + String tagName = null; + +// Test for and skip past these forms: +// <!-- ... --> +// <![ ... ]]> +// <! ... > +// <? ... ?> + + while (true) { + token = x.nextContent(); + if (token == XML.LT) { + token = x.nextToken(); + if (token instanceof Character) { + if (token == XML.SLASH) { + +// Close tag </ + + token = x.nextToken(); + if (!(token instanceof String)) { + throw new JSONException( + "Expected a closing name instead of '" + + token + "'."); + } + if (x.nextToken() != XML.GT) { + throw x.syntaxError("Misshaped close tag"); + } + return token; + } else if (token == XML.BANG) { + +// <! + + c = x.next(); + if (c == '-') { + if (x.next() == '-') { + x.skipPast("-->"); + } + x.back(); + } else if (c == '[') { + token = x.nextToken(); + if (token.equals("CDATA") && x.next() == '[') { + if (ja != null) { + ja.put(x.nextCDATA()); + } + } else { + throw x.syntaxError("Expected 'CDATA['"); + } + } else { + i = 1; + do { + token = x.nextMeta(); + if (token == null) { + throw x.syntaxError("Missing '>' after '<!'."); + } else if (token == XML.LT) { + i += 1; + } else if (token == XML.GT) { + i -= 1; + } + } while (i > 0); + } + } else if (token == XML.QUEST) { + +// <? + + x.skipPast("?>"); + } else { + throw x.syntaxError("Misshaped tag"); + } + +// Open tag < + + } else { + if (!(token instanceof String)) { + throw x.syntaxError("Bad tagName '" + token + "'."); + } + tagName = (String)token; + newja = new JSONArray(); + newjo = new JSONObject(); + if (arrayForm) { + newja.put(tagName); + if (ja != null) { + ja.put(newja); + } + } else { + newjo.put("tagName", tagName); + if (ja != null) { + ja.put(newjo); + } + } + token = null; + for (;;) { + if (token == null) { + token = x.nextToken(); + } + if (token == null) { + throw x.syntaxError("Misshaped tag"); + } + if (!(token instanceof String)) { + break; + } + +// attribute = value + + attribute = (String)token; + if (!arrayForm && (attribute == "tagName" || attribute == "childNode")) { + throw x.syntaxError("Reserved attribute."); + } + token = x.nextToken(); + if (token == XML.EQ) { + token = x.nextToken(); + if (!(token instanceof String)) { + throw x.syntaxError("Missing value"); + } + newjo.accumulate(attribute, JSONObject.stringToValue((String)token)); + token = null; + } else { + newjo.accumulate(attribute, ""); + } + } + if (arrayForm && newjo.length() > 0) { + newja.put(newjo); + } + +// Empty tag <.../> + + if (token == XML.SLASH) { + if (x.nextToken() != XML.GT) { + throw x.syntaxError("Misshaped tag"); + } + if (ja == null) { + if (arrayForm) { + return newja; + } else { + return newjo; + } + } + +// Content, between <...> and </...> + + } else { + if (token != XML.GT) { + throw x.syntaxError("Misshaped tag"); + } + closeTag = (String)parse(x, arrayForm, newja); + if (closeTag != null) { + if (!closeTag.equals(tagName)) { + throw x.syntaxError("Mismatched '" + tagName + + "' and '" + closeTag + "'"); + } + tagName = null; + if (!arrayForm && newja.length() > 0) { + newjo.put("childNodes", newja); + } + if (ja == null) { + if (arrayForm) { + return newja; + } else { + return newjo; + } + } + } + } + } + } else { + if (ja != null) { + ja.put(token instanceof String ? + JSONObject.stringToValue((String)token) : token); + } + } + } + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child tags. + * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored. + * @param string The source string. + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException + */ + public static JSONArray toJSONArray(String string) throws JSONException { + return toJSONArray(new XMLTokener(string)); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child content and tags. + * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored. + * @param x An XMLTokener. + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException + */ + public static JSONArray toJSONArray(XMLTokener x) throws JSONException { + return (JSONArray)parse(x, true, null); + } + + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored. + * @param x An XMLTokener of the XML source text. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException + */ + public static JSONObject toJSONObject(XMLTokener x) throws JSONException { + return (JSONObject)parse(x, false, null); + } + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored. + * @param string The XML source text. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException + */ + public static JSONObject toJSONObject(String string) throws JSONException { + return toJSONObject(new XMLTokener(string)); + } + + + /** + * Reverse the JSONML transformation, making an XML text from a JSONArray. + * @param ja A JSONArray. + * @return An XML string. + * @throws JSONException + */ + public static String toString(JSONArray ja) throws JSONException { + Object e; + int i; + JSONObject jo; + String k; + Iterator<String> keys; + int length; + StringBuffer sb = new StringBuffer(); + String tagName; + String v; + +// Emit <tagName + + tagName = ja.getString(0); + XML.noSpace(tagName); + tagName = XML.escape(tagName); + sb.append('<'); + sb.append(tagName); + + e = ja.opt(1); + if (e instanceof JSONObject) { + i = 2; + jo = (JSONObject)e; + +// Emit the attributes + + keys = jo.keys(); + while (keys.hasNext()) { + k = keys.next().toString(); + XML.noSpace(k); + v = jo.optString(k); + if (v != null) { + sb.append(' '); + sb.append(XML.escape(k)); + sb.append('='); + sb.append('"'); + sb.append(XML.escape(v)); + sb.append('"'); + } + } + } else { + i = 1; + } + +//Emit content in body + + length = ja.length(); + if (i >= length) { + sb.append('/'); + sb.append('>'); + } else { + sb.append('>'); + do { + e = ja.get(i); + i += 1; + if (e != null) { + if (e instanceof String) { + sb.append(XML.escape(e.toString())); + } else if (e instanceof JSONObject) { + sb.append(toString((JSONObject)e)); + } else if (e instanceof JSONArray) { + sb.append(toString((JSONArray)e)); + } + } + } while (i < length); + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + } + return sb.toString(); + } + + /** + * Reverse the JSONML transformation, making an XML text from a JSONObject. + * The JSONObject must contain a "tagName" property. If it has children, + * then it must have a "childNodes" property containing an array of objects. + * The other properties are attributes with string values. + * @param jo A JSONObject. + * @return An XML string. + * @throws JSONException + */ + public static String toString(JSONObject jo) throws JSONException { + StringBuffer sb = new StringBuffer(); + Object e; + int i; + JSONArray ja; + String k; + Iterator<String> keys; + int len; + String tagName; + String v; + +//Emit <tagName + + tagName = jo.optString("tagName"); + if (tagName == null) { + return XML.escape(jo.toString()); + } + XML.noSpace(tagName); + tagName = XML.escape(tagName); + sb.append('<'); + sb.append(tagName); + +//Emit the attributes + + keys = jo.keys(); + while (keys.hasNext()) { + k = keys.next().toString(); + if (!k.equals("tagName") && !k.equals("childNodes")) { + XML.noSpace(k); + v = jo.optString(k); + if (v != null) { + sb.append(' '); + sb.append(XML.escape(k)); + sb.append('='); + sb.append('"'); + sb.append(XML.escape(v)); + sb.append('"'); + } + } + } + +//Emit content in body + + ja = jo.optJSONArray("childNodes"); + if (ja == null) { + sb.append('/'); + sb.append('>'); + } else { + sb.append('>'); + len = ja.length(); + for (i = 0; i < len; i += 1) { + e = ja.get(i); + if (e != null) { + if (e instanceof String) { + sb.append(XML.escape(e.toString())); + } else if (e instanceof JSONObject) { + sb.append(toString((JSONObject)e)); + } else if (e instanceof JSONArray) { + sb.append(toString((JSONArray)e)); + } + } + } + sb.append('<'); + sb.append('/'); + sb.append(tagName); + sb.append('>'); + } + return sb.toString(); + } +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/json/JSONObject.java b/ncomp-utils-java/src/main/java/org/json/JSONObject.java new file mode 100644 index 0000000..4795082 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONObject.java @@ -0,0 +1,1598 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeSet; + +// Changed to make it ordered collection. + +/** + * A JSONObject is an unordered collection of name/value pairs. Its + * external form is a string wrapped in curly braces with colons between the + * names and values, and commas between the values and names. The internal form + * is an object having <code>get</code> and <code>opt</code> methods for + * accessing the values by name, and <code>put</code> methods for adding or + * replacing values by name. The values can be any of these types: + * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, + * <code>Number</code>, <code>String</code>, or the <code>JSONObject.NULL</code> + * object. A JSONObject constructor can be used to convert an external form + * JSON text into an internal form whose values can be retrieved with the + * <code>get</code> and <code>opt</code> methods, or to convert values into a + * JSON text using the <code>put</code> and <code>toString</code> methods. + * A <code>get</code> method returns a value if one can be found, and throws an + * exception if one cannot be found. An <code>opt</code> method returns a + * default value instead of throwing an exception, and so is useful for + * obtaining optional values. + * <p> + * The generic <code>get()</code> and <code>opt()</code> methods return an + * object, which you can cast or query for type. There are also typed + * <code>get</code> and <code>opt</code> methods that do type checking and type + * coercion for you. + * <p> + * The <code>put</code> methods adds values to an object. For example, <pre> + * myString = new JSONObject().put("JSON", "Hello, World!").toString();</pre> + * produces the string <code>{"JSON": "Hello, World"}</code>. + * <p> + * The texts produced by the <code>toString</code> methods strictly conform to + * the JSON syntax rules. + * The constructors are more forgiving in the texts they will accept: + * <ul> + * <li>An extra <code>,</code> <small>(comma)</small> may appear just + * before the closing brace.</li> + * <li>Strings may be quoted with <code>'</code> <small>(single + * quote)</small>.</li> + * <li>Strings do not need to be quoted at all if they do not begin with a quote + * or single quote, and if they do not contain leading or trailing spaces, + * and if they do not contain any of these characters: + * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers + * and if they are not the reserved words <code>true</code>, + * <code>false</code>, or <code>null</code>.</li> + * <li>Keys can be followed by <code>=</code> or <code>=></code> as well as + * by <code>:</code>.</li> + * <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as + * well as by <code>,</code> <small>(comma)</small>.</li> + * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or + * <code>0x-</code> <small>(hex)</small> prefix.</li> + * </ul> + * @author JSON.org + * @version 2009-03-06 + */ +public class JSONObject { + + /** + * JSONObject.NULL is equivalent to the value that JavaScript calls null, + * whilst Java's null is equivalent to the value that JavaScript calls + * undefined. + */ + private static final class Null { + + /** + * There is only intended to be a single instance of the NULL object, + * so the clone method returns itself. + * @return NULL. + */ + @Override + protected final Object clone() { + return this; + } + + + /** + * A Null object is equal to the null value and to itself. + * @param object An object to test for nullness. + * @return true if the object parameter is the JSONObject.NULL object + * or null. + */ + @Override + public boolean equals(Object object) { + return object == null || object == this; + } + + + /** + * Get the "null" string value. + * @return The string "null". + */ + @Override + public String toString() { + return "null"; + } + } + + + /** + * The map where the JSONObject's properties are kept. + */ + private Map<String, Object> map; + + + /** + * It is sometimes more convenient and less ambiguous to have a + * <code>NULL</code> object than to use Java's <code>null</code> value. + * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>. + * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>. + */ + public static final Object NULL = new Null(); + + + /** + * Construct an empty JSONObject. + */ + public JSONObject() { + this.map = new LinkedHashMap<String, Object>(); + } + + + /** + * Construct a JSONObject from a subset of another JSONObject. + * An array of strings is used to identify the keys that should be copied. + * Missing keys are ignored. + * @param jo A JSONObject. + * @param names An array of strings. + * @exception JSONException If a value is a non-finite number or if a name is duplicated. + */ + public JSONObject(JSONObject jo, String[] names) throws JSONException { + this(); + for (int i = 0; i < names.length; i += 1) { + putOnce(names[i], jo.opt(names[i])); + } + } + + + /** + * Construct a JSONObject from a JSONTokener. + * @param x A JSONTokener object containing the source string. + * @throws JSONException If there is a syntax error in the source string + * or a duplicated key. + */ + public JSONObject(JSONTokener x) throws JSONException { + this(); + char c; + String key; + + if (x.nextClean() != '{') { + throw x.syntaxError("A JSONObject text must begin with '{'"); + } + for (;;) { + c = x.nextClean(); + switch (c) { + case 0: + throw x.syntaxError("A JSONObject text must end with '}'"); + case '}': + return; + default: + x.back(); + key = x.nextValue().toString(); + } + + /* + * The key is followed by ':'. We will also tolerate '=' or '=>'. + */ + + c = x.nextClean(); + if (c == '=') { + if (x.next() != '>') { + x.back(); + } + } else if (c != ':') { + throw x.syntaxError("Expected a ':' after a key"); + } + putOnce(key, x.nextValue()); + + /* + * Pairs are separated by ','. We will also tolerate ';'. + */ + + switch (x.nextClean()) { + case ';': + case ',': + if (x.nextClean() == '}') { + return; + } + x.back(); + break; + case '}': + return; + default: + throw x.syntaxError("Expected a ',' or '}'"); + } + } + } + + + /** + * Construct a JSONObject from a Map. + * + * @param map A map object that can be used to initialize the contents of + * the JSONObject. + */ + public JSONObject(Map<String, Object> map) { + this.map = (map == null) ? new HashMap<String,Object>() : map; + } + + + /** + * Construct a JSONObject from a Map. + * + * Note: Use this constructor when the map contains <key,bean>. + * + * @param map - A map with Key-Bean data. + * @param includeSuperClass - Tell whether to include the super class properties. + */ + public JSONObject(Map<String, Object> map, boolean includeSuperClass) { + this.map = new HashMap<String, Object>(); + if (map != null) { + Iterator<Map.Entry<String, Object>> i = map.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry<String, Object> e = i.next(); + if (isStandardProperty(e.getValue().getClass())) { + this.map.put(e.getKey(), e.getValue()); + } else { + this.map.put(e.getKey(), new JSONObject(e.getValue(), + includeSuperClass)); + } + } + } + } + + + /** + * Construct a JSONObject from an Object using bean getters. + * It reflects on all of the public methods of the object. + * For each of the methods with no parameters and a name starting + * with <code>"get"</code> or <code>"is"</code> followed by an uppercase letter, + * the method is invoked, and a key and the value returned from the getter method + * are put into the new JSONObject. + * + * The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix. + * If the second remaining character is not upper case, then the first + * character is converted to lower case. + * + * For example, if an object has a method named <code>"getName"</code>, and + * if the result of calling <code>object.getName()</code> is <code>"Larry Fine"</code>, + * then the JSONObject will contain <code>"name": "Larry Fine"</code>. + * + * @param bean An object that has getter methods that should be used + * to make a JSONObject. + */ + public JSONObject(Object bean) { + this(); + populateInternalMap(bean, false); + } + + + /** + * Construct a JSONObject from an Object using bean getters. + * It reflects on all of the public methods of the object. + * For each of the methods with no parameters and a name starting + * with <code>"get"</code> or <code>"is"</code> followed by an uppercase letter, + * the method is invoked, and a key and the value returned from the getter method + * are put into the new JSONObject. + * + * The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix. + * If the second remaining character is not upper case, then the first + * character is converted to lower case. + * + * @param bean An object that has getter methods that should be used + * to make a JSONObject. + * @param includeSuperClass If true, include the super class properties. + */ + public JSONObject(Object bean, boolean includeSuperClass) { + this(); + populateInternalMap(bean, includeSuperClass); + } + + private void populateInternalMap(Object bean, boolean includeSuperClass){ + Class<? extends Object> klass = bean.getClass(); + + /* If klass.getSuperClass is System class then force includeSuperClass to false. */ + + if (klass.getClassLoader() == null) { + includeSuperClass = false; + } + + Method[] methods = (includeSuperClass) ? + klass.getMethods() : klass.getDeclaredMethods(); + for (int i = 0; i < methods.length; i += 1) { + try { + Method method = methods[i]; + if (Modifier.isPublic(method.getModifiers())) { + String name = method.getName(); + String key = ""; + if (name.startsWith("get")) { + key = name.substring(3); + } else if (name.startsWith("is")) { + key = name.substring(2); + } + if (key.length() > 0 && + Character.isUpperCase(key.charAt(0)) && + method.getParameterTypes().length == 0) { + if (key.length() == 1) { + key = key.toLowerCase(); + } else if (!Character.isUpperCase(key.charAt(1))) { + key = key.substring(0, 1).toLowerCase() + + key.substring(1); + } + + Object result = method.invoke(bean, (Object[])null); + if (result == null) { + map.put(key, NULL); + } else if (result.getClass().isArray()) { + map.put(key, new JSONArray(result, includeSuperClass)); + } else if (result instanceof Collection) { // List or Set + map.put(key, new JSONArray((Collection<?>)result, includeSuperClass)); + } else if (result instanceof Map) { + map.put(key, new JSONObject((Map<?, ?>)result, includeSuperClass)); + } else if (isStandardProperty(result.getClass())) { // Primitives, String and Wrapper + map.put(key, result); + } else { + if (result.getClass().getPackage().getName().startsWith("java") || + result.getClass().getClassLoader() == null) { + map.put(key, result.toString()); + } else { // User defined Objects + map.put(key, new JSONObject(result, includeSuperClass)); + } + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + + static boolean isStandardProperty(Class<? extends Object> clazz) { + return clazz.isPrimitive() || + clazz.isAssignableFrom(Byte.class) || + clazz.isAssignableFrom(Short.class) || + clazz.isAssignableFrom(Integer.class) || + clazz.isAssignableFrom(Long.class) || + clazz.isAssignableFrom(Float.class) || + clazz.isAssignableFrom(Double.class) || + clazz.isAssignableFrom(Character.class) || + clazz.isAssignableFrom(String.class) || + clazz.isAssignableFrom(Boolean.class); + } + + + /** + * Construct a JSONObject from an Object, using reflection to find the + * public members. The resulting JSONObject's keys will be the strings + * from the names array, and the values will be the field values associated + * with those keys in the object. If a key is not found or not visible, + * then it will not be copied into the new JSONObject. + * @param object An object that has fields that should be used to make a + * JSONObject. + * @param names An array of strings, the names of the fields to be obtained + * from the object. + */ + public JSONObject(Object object, String names[]) { + this(); + Class<? extends Object> c = object.getClass(); + for (int i = 0; i < names.length; i += 1) { + String name = names[i]; + try { + putOpt(name, c.getField(name).get(object)); + } catch (Exception e) { + /* forget about it */ + } + } + } + + + /** + * Construct a JSONObject from a source JSON text string. + * This is the most commonly used JSONObject constructor. + * @param source A string beginning + * with <code>{</code> <small>(left brace)</small> and ending + * with <code>}</code> <small>(right brace)</small>. + * @exception JSONException If there is a syntax error in the source + * string or a duplicated key. + */ + public JSONObject(String source) throws JSONException { + this(new JSONTokener(source)); + } + + + /** + * Accumulate values under a key. It is similar to the put method except + * that if there is already an object stored under the key then a + * JSONArray is stored under the key to hold all of the accumulated values. + * If there is already a JSONArray, then the new value is appended to it. + * In contrast, the put method replaces the previous value. + * @param key A key string. + * @param value An object to be accumulated under the key. + * @return this. + * @throws JSONException If the value is an invalid number + * or if the key is null. + */ + public JSONObject accumulate(String key, Object value) + throws JSONException { + testValidity(value); + Object o = opt(key); + if (o == null) { + put(key, value instanceof JSONArray ? + new JSONArray().put(value) : + value); + } else if (o instanceof JSONArray) { + ((JSONArray)o).put(value); + } else { + put(key, new JSONArray().put(o).put(value)); + } + return this; + } + + + /** + * Append values to the array under a key. If the key does not exist in the + * JSONObject, then the key is put in the JSONObject with its value being a + * JSONArray containing the value parameter. If the key was already + * associated with a JSONArray, then the value parameter is appended to it. + * @param key A key string. + * @param value An object to be accumulated under the key. + * @return this. + * @throws JSONException If the key is null or if the current value + * associated with the key is not a JSONArray. + */ + public JSONObject append(String key, Object value) + throws JSONException { + testValidity(value); + Object o = opt(key); + if (o == null) { + put(key, new JSONArray().put(value)); + } else if (o instanceof JSONArray) { + put(key, ((JSONArray)o).put(value)); + } else { + throw new JSONException("JSONObject[" + key + + "] is not a JSONArray."); + } + return this; + } + + + /** + * Produce a string from a double. The string "null" will be returned if + * the number is not finite. + * @param d A double. + * @return A String. + */ + static public String doubleToString(double d) { + if (Double.isInfinite(d) || Double.isNaN(d)) { + return "null"; + } + +// Shave off trailing zeros and decimal point, if possible. + + String s = Double.toString(d); + if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { + while (s.endsWith("0")) { + s = s.substring(0, s.length() - 1); + } + if (s.endsWith(".")) { + s = s.substring(0, s.length() - 1); + } + } + return s; + } + + + /** + * Get the value object associated with a key. + * + * @param key A key string. + * @return The object associated with the key. + * @throws JSONException if the key is not found. + */ + public Object get(String key) throws JSONException { + Object o = opt(key); + if (o == null) { + throw new JSONException("JSONObject[" + quote(key) + + "] not found."); + } + return o; + } + + + /** + * Get the boolean value associated with a key. + * + * @param key A key string. + * @return The truth. + * @throws JSONException + * if the value is not a Boolean or the String "true" or "false". + */ + public boolean getBoolean(String key) throws JSONException { + Object o = get(key); + if (o.equals(Boolean.FALSE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("false"))) { + return false; + } else if (o.equals(Boolean.TRUE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("true"))) { + return true; + } + throw new JSONException("JSONObject[" + quote(key) + + "] is not a Boolean."); + } + + + /** + * Get the double value associated with a key. + * @param key A key string. + * @return The numeric value. + * @throws JSONException if the key is not found or + * if the value is not a Number object and cannot be converted to a number. + */ + public double getDouble(String key) throws JSONException { + Object o = get(key); + try { + return o instanceof Number ? + ((Number)o).doubleValue() : + Double.valueOf((String)o).doubleValue(); + } catch (Exception e) { + throw new JSONException("JSONObject[" + quote(key) + + "] is not a number."); + } + } + + + /** + * Get the int value associated with a key. If the number value is too + * large for an int, it will be clipped. + * + * @param key A key string. + * @return The integer value. + * @throws JSONException if the key is not found or if the value cannot + * be converted to an integer. + */ + public int getInt(String key) throws JSONException { + Object o = get(key); + return o instanceof Number ? + ((Number)o).intValue() : (int)getDouble(key); + } + + + /** + * Get the JSONArray value associated with a key. + * + * @param key A key string. + * @return A JSONArray which is the value. + * @throws JSONException if the key is not found or + * if the value is not a JSONArray. + */ + public JSONArray getJSONArray(String key) throws JSONException { + Object o = get(key); + if (o instanceof JSONArray) { + return (JSONArray)o; + } + throw new JSONException("JSONObject[" + quote(key) + + "] is not a JSONArray."); + } + + + /** + * Get the JSONObject value associated with a key. + * + * @param key A key string. + * @return A JSONObject which is the value. + * @throws JSONException if the key is not found or + * if the value is not a JSONObject. + */ + public JSONObject getJSONObject(String key) throws JSONException { + Object o = get(key); + if (o instanceof JSONObject) { + return (JSONObject)o; + } + throw new JSONException("JSONObject[" + quote(key) + + "] is not a JSONObject."); + } + + + /** + * Get the long value associated with a key. If the number value is too + * long for a long, it will be clipped. + * + * @param key A key string. + * @return The long value. + * @throws JSONException if the key is not found or if the value cannot + * be converted to a long. + */ + public long getLong(String key) throws JSONException { + Object o = get(key); + return o instanceof Number ? + ((Number)o).longValue() : (long)getDouble(key); + } + + + /** + * Get an array of field names from a JSONObject. + * + * @return An array of field names, or null if there are no names. + */ + public static String[] getNames(JSONObject jo) { + int length = jo.length(); + if (length == 0) { + return null; + } + Iterator<String> i = jo.keys(); + String[] names = new String[length]; + int j = 0; + while (i.hasNext()) { + names[j] = i.next(); + j += 1; + } + return names; + } + + + /** + * Get an array of field names from an Object. + * + * @return An array of field names, or null if there are no names. + */ + public static String[] getNames(Object object) { + if (object == null) { + return null; + } + Class<? extends Object> klass = object.getClass(); + Field[] fields = klass.getFields(); + int length = fields.length; + if (length == 0) { + return null; + } + String[] names = new String[length]; + for (int i = 0; i < length; i += 1) { + names[i] = fields[i].getName(); + } + return names; + } + + + /** + * Get the string associated with a key. + * + * @param key A key string. + * @return A string which is the value. + * @throws JSONException if the key is not found. + */ + public String getString(String key) throws JSONException { + return get(key).toString(); + } + + + /** + * Determine if the JSONObject contains a specific key. + * @param key A key string. + * @return true if the key exists in the JSONObject. + */ + public boolean has(String key) { + return this.map.containsKey(key); + } + + + /** + * Determine if the value associated with the key is null or if there is + * no value. + * @param key A key string. + * @return true if there is no value associated with the key or if + * the value is the JSONObject.NULL object. + */ + public boolean isNull(String key) { + return JSONObject.NULL.equals(opt(key)); + } + + + /** + * Get an enumeration of the keys of the JSONObject. + * + * @return An iterator of the keys. + */ + public Iterator<String> keys() { + return this.map.keySet().iterator(); + } + + + /** + * Get the number of keys stored in the JSONObject. + * + * @return The number of keys in the JSONObject. + */ + public int length() { + return this.map.size(); + } + + + /** + * Produce a JSONArray containing the names of the elements of this + * JSONObject. + * @return A JSONArray containing the key strings, or null if the JSONObject + * is empty. + */ + public JSONArray names() { + JSONArray ja = new JSONArray(); + Iterator<String> keys = keys(); + while (keys.hasNext()) { + ja.put(keys.next()); + } + return ja.length() == 0 ? null : ja; + } + + /** + * Produce a string from a Number. + * @param n A Number + * @return A String. + * @throws JSONException If n is a non-finite number. + */ + static public String numberToString(Number n) + throws JSONException { + if (n == null) { + throw new JSONException("Null pointer"); + } + testValidity(n); + +// Shave off trailing zeros and decimal point, if possible. + + String s = n.toString(); + if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { + while (s.endsWith("0")) { + s = s.substring(0, s.length() - 1); + } + if (s.endsWith(".")) { + s = s.substring(0, s.length() - 1); + } + } + return s; + } + + + /** + * Get an optional value associated with a key. + * @param key A key string. + * @return An object which is the value, or null if there is no value. + */ + public Object opt(String key) { + return key == null ? null : this.map.get(key); + } + + + /** + * Get an optional boolean associated with a key. + * It returns false if there is no such key, or if the value is not + * Boolean.TRUE or the String "true". + * + * @param key A key string. + * @return The truth. + */ + public boolean optBoolean(String key) { + return optBoolean(key, false); + } + + + /** + * Get an optional boolean associated with a key. + * It returns the defaultValue if there is no such key, or if it is not + * a Boolean or the String "true" or "false" (case insensitive). + * + * @param key A key string. + * @param defaultValue The default. + * @return The truth. + */ + public boolean optBoolean(String key, boolean defaultValue) { + try { + return getBoolean(key); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONArray which is produced from a Collection. + * @param key A key string. + * @param value A Collection value. + * @return this. + * @throws JSONException + */ + public JSONObject put(String key, Collection<?> value) throws JSONException { + put(key, new JSONArray(value)); + return this; + } + + + /** + * Get an optional double associated with a key, + * or NaN if there is no such key or if its value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A string which is the key. + * @return An object which is the value. + */ + public double optDouble(String key) { + return optDouble(key, Double.NaN); + } + + + /** + * Get an optional double associated with a key, or the + * defaultValue if there is no such key or if its value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public double optDouble(String key, double defaultValue) { + try { + Object o = opt(key); + return o instanceof Number ? ((Number)o).doubleValue() : + new Double((String)o).doubleValue(); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get an optional int value associated with a key, + * or zero if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public int optInt(String key) { + return optInt(key, 0); + } + + + /** + * Get an optional int value associated with a key, + * or the default if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public int optInt(String key, int defaultValue) { + try { + return getInt(key); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get an optional JSONArray associated with a key. + * It returns null if there is no such key, or if its value is not a + * JSONArray. + * + * @param key A key string. + * @return A JSONArray which is the value. + */ + public JSONArray optJSONArray(String key) { + Object o = opt(key); + return o instanceof JSONArray ? (JSONArray)o : null; + } + + + /** + * Get an optional JSONObject associated with a key. + * It returns null if there is no such key, or if its value is not a + * JSONObject. + * + * @param key A key string. + * @return A JSONObject which is the value. + */ + public JSONObject optJSONObject(String key) { + Object o = opt(key); + return o instanceof JSONObject ? (JSONObject)o : null; + } + + + /** + * Get an optional long value associated with a key, + * or zero if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public long optLong(String key) { + return optLong(key, 0); + } + + + /** + * Get an optional long value associated with a key, + * or the default if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public long optLong(String key, long defaultValue) { + try { + return getLong(key); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get an optional string associated with a key. + * It returns an empty string if there is no such key. If the value is not + * a string and is not null, then it is coverted to a string. + * + * @param key A key string. + * @return A string which is the value. + */ + public String optString(String key) { + return optString(key, ""); + } + + + /** + * Get an optional string associated with a key. + * It returns the defaultValue if there is no such key. + * + * @param key A key string. + * @param defaultValue The default. + * @return A string which is the value. + */ + public String optString(String key, String defaultValue) { + Object o = opt(key); + return o != null ? o.toString() : defaultValue; + } + + + /** + * Put a key/boolean pair in the JSONObject. + * + * @param key A key string. + * @param value A boolean which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(String key, boolean value) throws JSONException { + put(key, value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + + /** + * Put a key/double pair in the JSONObject. + * + * @param key A key string. + * @param value A double which is the value. + * @return this. + * @throws JSONException If the key is null or if the number is invalid. + */ + public JSONObject put(String key, double value) throws JSONException { + put(key, new Double(value)); + return this; + } + + + /** + * Put a key/int pair in the JSONObject. + * + * @param key A key string. + * @param value An int which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(String key, int value) throws JSONException { + put(key, new Integer(value)); + return this; + } + + + /** + * Put a key/long pair in the JSONObject. + * + * @param key A key string. + * @param value A long which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(String key, long value) throws JSONException { + put(key, new Long(value)); + return this; + } + + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONObject which is produced from a Map. + * @param key A key string. + * @param value A Map value. + * @return this. + * @throws JSONException + */ + public JSONObject put(String key, Map<?, ?> value) throws JSONException { + put(key, new JSONObject(value)); + return this; + } + + + /** + * Put a key/value pair in the JSONObject. If the value is null, + * then the key will be removed from the JSONObject if it is present. + * @param key A key string. + * @param value An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, + * or the JSONObject.NULL object. + * @return this. + * @throws JSONException If the value is non-finite number + * or if the key is null. + */ + public JSONObject put(String key, Object value) throws JSONException { + if (key == null) { + throw new JSONException("Null key."); + } + if (value != null) { + testValidity(value); + this.map.put(key, value); + } else { + remove(key); + } + return this; + } + + + /** + * Put a key/value pair in the JSONObject, but only if the key and the + * value are both non-null, and only if there is not already a member + * with that name. + * @param key + * @param value + * @return his. + * @throws JSONException if the key is a duplicate + */ + public JSONObject putOnce(String key, Object value) throws JSONException { + if (key != null && value != null) { + if (opt(key) != null) { + throw new JSONException("Duplicate key \"" + key + "\""); + } + put(key, value); + } + return this; + } + + + /** + * Put a key/value pair in the JSONObject, but only if the + * key and the value are both non-null. + * @param key A key string. + * @param value An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, + * or the JSONObject.NULL object. + * @return this. + * @throws JSONException If the value is a non-finite number. + */ + public JSONObject putOpt(String key, Object value) throws JSONException { + if (key != null && value != null) { + put(key, value); + } + return this; + } + + + /** + * Produce a string in double quotes with backslash sequences in all the + * right places. A backslash will be inserted within </, allowing JSON + * text to be delivered in HTML. In JSON text, a string cannot contain a + * control character or an unescaped quote or backslash. + * @param string A String + * @return A String correctly formatted for insertion in a JSON text. + */ + public static String quote(String string) { + if (string == null || string.length() == 0) { + return "\"\""; + } + + char b; + char c = 0; + int i; + int len = string.length(); + StringBuffer sb = new StringBuffer(len + 4); + String t; + + sb.append('"'); + for (i = 0; i < len; i += 1) { + b = c; + c = string.charAt(i); + switch (c) { + case '\\': + case '"': + sb.append('\\'); + sb.append(c); + break; + case '/': + if (b == '<') { + sb.append('\\'); + } + sb.append(c); + break; + case '\b': + sb.append("\\b"); + break; + case '\t': + sb.append("\\t"); + break; + case '\n': + sb.append("\\n"); + break; + case '\f': + sb.append("\\f"); + break; + case '\r': + sb.append("\\r"); + break; + default: + if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || + (c >= '\u2000' && c < '\u2100')) { + t = "000" + Integer.toHexString(c); + sb.append("\\u" + t.substring(t.length() - 4)); + } else { + sb.append(c); + } + } + } + sb.append('"'); + return sb.toString(); + } + + /** + * Remove a name and its value, if present. + * @param key The name to be removed. + * @return The value that was associated with the name, + * or null if there was no value. + */ + public Object remove(String key) { + return this.map.remove(key); + } + + /** + * Get an enumeration of the keys of the JSONObject. + * The keys will be sorted alphabetically. + * + * @return An iterator of the keys. + */ + public Iterator<String> sortedKeys() { + return new TreeSet<String>(this.map.keySet()).iterator(); + } + + /** + * Try to convert a string into a number, boolean, or null. If the string + * can't be converted, return the string. + * @param s A String. + * @return A simple JSON value. + */ + static public Object stringToValue(String s) { + if (s.equals("")) { + return s; + } + if (s.equalsIgnoreCase("true")) { + return Boolean.TRUE; + } + if (s.equalsIgnoreCase("false")) { + return Boolean.FALSE; + } + if (s.equalsIgnoreCase("null")) { + return JSONObject.NULL; + } + + /* + * If it might be a number, try converting it. We support the 0- and 0x- + * conventions. If a number cannot be produced, then the value will just + * be a string. Note that the 0-, 0x-, plus, and implied string + * conventions are non-standard. A JSON parser is free to accept + * non-JSON forms as long as it accepts all correct JSON forms. + */ + + char b = s.charAt(0); + if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { + if (b == '0') { + if (s.length() > 2 && + (s.charAt(1) == 'x' || s.charAt(1) == 'X')) { + try { + return new Integer(Integer.parseInt(s.substring(2), + 16)); + } catch (Exception e) { + /* Ignore the error */ + } + } else { + try { + return new Integer(Integer.parseInt(s, 8)); + } catch (Exception e) { + /* Ignore the error */ + } + } + } + try { + if (s.indexOf('.') > -1 || s.indexOf('e') > -1 || s.indexOf('E') > -1) { + return Double.valueOf(s); + } else { + Long myLong = new Long(s); + if (myLong.longValue() == myLong.intValue()) { + return new Integer(myLong.intValue()); + } else { + return myLong; + } + } + } catch (Exception f) { + /* Ignore the error */ + } + } + return s; + } + + + /** + * Throw an exception if the object is an NaN or infinite number. + * @param o The object to test. + * @throws JSONException If o is a non-finite number. + */ + static void testValidity(Object o) throws JSONException { + if (o != null) { + if (o instanceof Double) { + if (((Double)o).isInfinite() || ((Double)o).isNaN()) { + throw new JSONException( + "JSON does not allow non-finite numbers."); + } + } else if (o instanceof Float) { + if (((Float)o).isInfinite() || ((Float)o).isNaN()) { + throw new JSONException( + "JSON does not allow non-finite numbers."); + } + } + } + } + + + /** + * Produce a JSONArray containing the values of the members of this + * JSONObject. + * @param names A JSONArray containing a list of key strings. This + * determines the sequence of the values in the result. + * @return A JSONArray of values. + * @throws JSONException If any of the values are non-finite numbers. + */ + public JSONArray toJSONArray(JSONArray names) throws JSONException { + if (names == null || names.length() == 0) { + return null; + } + JSONArray ja = new JSONArray(); + for (int i = 0; i < names.length(); i += 1) { + ja.put(this.opt(names.getString(i))); + } + return ja; + } + + /** + * Make a JSON text of this JSONObject. For compactness, no whitespace + * is added. If this would not result in a syntactically correct JSON text, + * then null will be returned instead. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * + * @return a printable, displayable, portable, transmittable + * representation of the object, beginning + * with <code>{</code> <small>(left brace)</small> and ending + * with <code>}</code> <small>(right brace)</small>. + */ + @Override + public String toString() { + try { + Iterator<String> keys = keys(); + StringBuffer sb = new StringBuffer("{"); + + while (keys.hasNext()) { + if (sb.length() > 1) { + sb.append(','); + } + Object o = keys.next(); + sb.append(quote(o.toString())); + sb.append(':'); + sb.append(valueToString(this.map.get(o))); + } + sb.append('}'); + return sb.toString(); + } catch (Exception e) { + return null; + } + } + + + /** + * Make a prettyprinted JSON text of this JSONObject. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @return a printable, displayable, portable, transmittable + * representation of the object, beginning + * with <code>{</code> <small>(left brace)</small> and ending + * with <code>}</code> <small>(right brace)</small>. + * @throws JSONException If the object contains an invalid number. + */ + public String toString(int indentFactor) throws JSONException { + return toString(indentFactor, 0); + } + + + /** + * Make a prettyprinted JSON text of this JSONObject. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indentation of the top level. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with <code>{</code> <small>(left brace)</small> and ending + * with <code>}</code> <small>(right brace)</small>. + * @throws JSONException If the object contains an invalid number. + */ + String toString(int indentFactor, int indent) throws JSONException { + int j; + int n = length(); + if (n == 0) { + return "{}"; + } +// Iterator<String> keys = sortedKeys(); + Iterator<String> keys = map.keySet().iterator(); + StringBuffer sb = new StringBuffer("{"); + int newindent = indent + indentFactor; + Object o; + if (n == 1) { + o = keys.next(); + sb.append(quote(o.toString())); + sb.append(": "); + sb.append(valueToString(this.map.get(o), indentFactor, + indent)); + } else { + while (keys.hasNext()) { + o = keys.next(); + if (sb.length() > 1) { + sb.append(",\n"); + } else { + sb.append('\n'); + } + for (j = 0; j < newindent; j += 1) { + sb.append(' '); + } + sb.append(quote(o.toString())); + sb.append(": "); + sb.append(valueToString(this.map.get(o), indentFactor, + newindent)); + } + if (sb.length() > 1) { + sb.append('\n'); + for (j = 0; j < indent; j += 1) { + sb.append(' '); + } + } + } + sb.append('}'); + return sb.toString(); + } + + + /** + * Make a JSON text of an Object value. If the object has an + * value.toJSONString() method, then that method will be used to produce + * the JSON text. The method is required to produce a strictly + * conforming text. If the object does not contain a toJSONString + * method (which is the most common case), then a text will be + * produced by other means. If the value is an array or Collection, + * then a JSONArray will be made from it and its toJSONString method + * will be called. If the value is a MAP, then a JSONObject will be made + * from it and its toJSONString method will be called. Otherwise, the + * value's toString method will be called, and the result will be quoted. + * + * <p> + * Warning: This method assumes that the data structure is acyclical. + * @param value The value to be serialized. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with <code>{</code> <small>(left brace)</small> and ending + * with <code>}</code> <small>(right brace)</small>. + * @throws JSONException If the value is or contains an invalid number. + */ + static String valueToString(Object value) throws JSONException { + if (value == null || value.equals(null)) { + return "null"; + } + if (value instanceof JSONString) { + Object o; + try { + o = ((JSONString)value).toJSONString(); + } catch (Exception e) { + throw new JSONException(e); + } + if (o instanceof String) { + return (String)o; + } + throw new JSONException("Bad value from toJSONString: " + o); + } + if (value instanceof Number) { + return numberToString((Number) value); + } + if (value instanceof Boolean || value instanceof JSONObject || + value instanceof JSONArray) { + return value.toString(); + } + if (value instanceof Map) { + return new JSONObject((Map<?, ?>)value).toString(); + } + if (value instanceof Collection) { + return new JSONArray((Collection<?>)value).toString(); + } + if (value.getClass().isArray()) { + return new JSONArray(value).toString(); + } + return quote(value.toString()); + } + + + /** + * Make a prettyprinted JSON text of an object value. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * @param value The value to be serialized. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indentation of the top level. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with <code>{</code> <small>(left brace)</small> and ending + * with <code>}</code> <small>(right brace)</small>. + * @throws JSONException If the object contains an invalid number. + */ + public static String valueToString(Object value, int indentFactor, int indent) + throws JSONException { + if (value == null || value.equals(null)) { + return "null"; + } + try { + if (value instanceof JSONString) { + Object o = ((JSONString)value).toJSONString(); + if (o instanceof String) { + return (String)o; + } + } + } catch (Exception e) { + /* forget about it */ + } + if (value instanceof Number) { + return numberToString((Number) value); + } + if (value instanceof Boolean) { + return value.toString(); + } + if (value instanceof JSONObject) { + return ((JSONObject)value).toString(indentFactor, indent); + } + if (value instanceof JSONArray) { + return ((JSONArray)value).toString(indentFactor, indent); + } + if (value instanceof Map) { + return new JSONObject((Map<?, ?>)value).toString(indentFactor, indent); + } + if (value instanceof Collection) { + return new JSONArray((Collection<?>)value).toString(indentFactor, indent); + } + if (value.getClass().isArray()) { + return new JSONArray(value).toString(indentFactor, indent); + } + return quote(value.toString()); + } + + + /** + * Write the contents of the JSONObject as JSON text to a writer. + * For compactness, no whitespace is added. + * <p> + * Warning: This method assumes that the data structure is acyclical. + * + * @return The writer. + * @throws JSONException + */ + public Writer write(Writer writer) throws JSONException { + try { + boolean b = false; + Iterator<String> keys = keys(); + writer.write('{'); + + while (keys.hasNext()) { + if (b) { + writer.write(','); + } + Object k = keys.next(); + writer.write(quote(k.toString())); + writer.write(':'); + Object v = this.map.get(k); + if (v instanceof JSONObject) { + ((JSONObject)v).write(writer); + } else if (v instanceof JSONArray) { + ((JSONArray)v).write(writer); + } else { + writer.write(valueToString(v)); + } + b = true; + } + writer.write('}'); + return writer; + } catch (IOException e) { + throw new JSONException(e); + } + } +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/json/JSONString.java b/ncomp-utils-java/src/main/java/org/json/JSONString.java new file mode 100644 index 0000000..bb89197 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONString.java @@ -0,0 +1,39 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; +/** + * The <code>JSONString</code> interface allows a <code>toJSONString()</code> + * method so that a class can change the behavior of + * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, + * and <code>JSONWriter.value(</code>Object<code>)</code>. The + * <code>toJSONString</code> method will be used instead of the default behavior + * of using the Object's <code>toString()</code> method and quoting the result. + */ +public interface JSONString { + /** + * The <code>toJSONString</code> method allows a class to produce its own JSON + * serialization. + * + * @return A strictly syntactically correct JSON text. + */ + public String toJSONString(); +} diff --git a/ncomp-utils-java/src/main/java/org/json/JSONStringer.java b/ncomp-utils-java/src/main/java/org/json/JSONStringer.java new file mode 100644 index 0000000..f725b0c --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONStringer.java @@ -0,0 +1,100 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2006 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.io.StringWriter; + +/** + * JSONStringer provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONStringer can produce one JSON text. + * <p> + * A JSONStringer instance provides a <code>value</code> method for appending + * values to the + * text, and a <code>key</code> + * method for adding keys before values in objects. There are <code>array</code> + * and <code>endArray</code> methods that make and bound array values, and + * <code>object</code> and <code>endObject</code> methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting cascade style. For example, <pre> + * myString = new JSONStringer() + * .object() + * .key("JSON") + * .value("Hello, World!") + * .endObject() + * .toString();</pre> which produces the string <pre> + * {"JSON":"Hello, World!"}</pre> + * <p> + * The first method called must be <code>array</code> or <code>object</code>. + * There are no methods for adding commas or colons. JSONStringer adds them for + * you. Objects and arrays can be nested up to 20 levels deep. + * <p> + * This can sometimes be easier than using a JSONObject to build a string. + * @author JSON.org + * @version 2008-09-18 + */ +public class JSONStringer extends JSONWriter { + /** + * Make a fresh JSONStringer. It can be used to build one JSON text. + */ + public JSONStringer() { + super(new StringWriter()); + } + + /** + * Return the JSON text. This method is used to obtain the product of the + * JSONStringer instance. It will return <code>null</code> if there was a + * problem in the construction of the JSON text (such as the calls to + * <code>array</code> were not properly balanced with calls to + * <code>endArray</code>). + * @return The JSON text. + */ + @Override + public String toString() { + return this.mode == 'd' ? this.writer.toString() : null; + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/JSONTokener.java b/ncomp-utils-java/src/main/java/org/json/JSONTokener.java new file mode 100644 index 0000000..1064db5 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONTokener.java @@ -0,0 +1,447 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * A JSONTokener takes a source string and extracts characters and tokens from + * it. It is used by the JSONObject and JSONArray constructors to parse + * JSON source strings. + * @author JSON.org + * @version 2008-09-18 + */ +public class JSONTokener { + + private int index; + private Reader reader; + private char lastChar; + private boolean useLastChar; + + + /** + * Construct a JSONTokener from a string. + * + * @param reader A reader. + */ + public JSONTokener(Reader reader) { + this.reader = reader.markSupported() ? + reader : new BufferedReader(reader); + this.useLastChar = false; + this.index = 0; + } + + + /** + * Construct a JSONTokener from a string. + * + * @param s A source string. + */ + public JSONTokener(String s) { + this(new StringReader(s)); + } + + + /** + * Back up one character. This provides a sort of lookahead capability, + * so that you can test for a digit or letter before attempting to parse + * the next number or identifier. + */ + public void back() throws JSONException { + if (useLastChar || index <= 0) { + throw new JSONException("Stepping back two steps is not supported"); + } + index -= 1; + useLastChar = true; + } + + + + /** + * Get the hex value of a character (base16). + * @param c A character between '0' and '9' or between 'A' and 'F' or + * between 'a' and 'f'. + * @return An int between 0 and 15, or -1 if c was not a hex digit. + */ + public static int dehexchar(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'A' && c <= 'F') { + return c - ('A' - 10); + } + if (c >= 'a' && c <= 'f') { + return c - ('a' - 10); + } + return -1; + } + + + /** + * Determine if the source string still contains characters that next() + * can consume. + * @return true if not yet at the end of the source. + */ + public boolean more() throws JSONException { + char nextChar = next(); + if (nextChar == 0) { + return false; + } + back(); + return true; + } + + + /** + * Get the next character in the source string. + * + * @return The next character, or 0 if past the end of the source string. + */ + public char next() throws JSONException { + if (this.useLastChar) { + this.useLastChar = false; + if (this.lastChar != 0) { + this.index += 1; + } + return this.lastChar; + } + int c; + try { + c = this.reader.read(); + } catch (IOException exc) { + throw new JSONException(exc); + } + + if (c <= 0) { // End of stream + this.lastChar = 0; + return 0; + } + this.index += 1; + this.lastChar = (char) c; + return this.lastChar; + } + + + /** + * Consume the next character, and check that it matches a specified + * character. + * @param c The character to match. + * @return The character. + * @throws JSONException if the character does not match. + */ + public char next(char c) throws JSONException { + char n = next(); + if (n != c) { + throw syntaxError("Expected '" + c + "' and instead saw '" + + n + "'"); + } + return n; + } + + + /** + * Get the next n characters. + * + * @param n The number of characters to take. + * @return A string of n characters. + * @throws JSONException + * Substring bounds error if there are not + * n characters remaining in the source string. + */ + public String next(int n) throws JSONException { + if (n == 0) { + return ""; + } + + char[] buffer = new char[n]; + int pos = 0; + + if (this.useLastChar) { + this.useLastChar = false; + buffer[0] = this.lastChar; + pos = 1; + } + + try { + int len; + while ((pos < n) && ((len = reader.read(buffer, pos, n - pos)) != -1)) { + pos += len; + } + } catch (IOException exc) { + throw new JSONException(exc); + } + this.index += pos; + + if (pos < n) { + throw syntaxError("Substring bounds error"); + } + + this.lastChar = buffer[n - 1]; + return new String(buffer); + } + + + /** + * Get the next char in the string, skipping whitespace. + * @throws JSONException + * @return A character, or 0 if there are no more characters. + */ + public char nextClean() throws JSONException { + for (;;) { + char c = next(); + if (c == 0 || c > ' ') { + return c; + } + } + } + + + /** + * Return the characters up to the next close quote character. + * Backslash processing is done. The formal JSON format does not + * allow strings in single quotes, but an implementation is allowed to + * accept them. + * @param quote The quoting character, either + * <code>"</code> <small>(double quote)</small> or + * <code>'</code> <small>(single quote)</small>. + * @return A String. + * @throws JSONException Unterminated string. + */ + public String nextString(char quote) throws JSONException { + char c; + StringBuffer sb = new StringBuffer(); + for (;;) { + c = next(); + switch (c) { + case 0: + case '\n': + case '\r': + throw syntaxError("Unterminated string"); + case '\\': + c = next(); + switch (c) { + case 'b': + sb.append('\b'); + break; + case 't': + sb.append('\t'); + break; + case 'n': + sb.append('\n'); + break; + case 'f': + sb.append('\f'); + break; + case 'r': + sb.append('\r'); + break; + case 'u': + sb.append((char)Integer.parseInt(next(4), 16)); + break; + case '"': + case '\'': + case '\\': + case '/': + sb.append(c); + break; + default: + throw syntaxError("Illegal escape."); + } + break; + default: + if (c == quote) { + return sb.toString(); + } + sb.append(c); + } + } + } + + + /** + * Get the text up but not including the specified character or the + * end of line, whichever comes first. + * @param d A delimiter character. + * @return A string. + */ + public String nextTo(char d) throws JSONException { + StringBuffer sb = new StringBuffer(); + for (;;) { + char c = next(); + if (c == d || c == 0 || c == '\n' || c == '\r') { + if (c != 0) { + back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + + /** + * Get the text up but not including one of the specified delimiter + * characters or the end of line, whichever comes first. + * @param delimiters A set of delimiter characters. + * @return A string, trimmed. + */ + public String nextTo(String delimiters) throws JSONException { + char c; + StringBuffer sb = new StringBuffer(); + for (;;) { + c = next(); + if (delimiters.indexOf(c) >= 0 || c == 0 || + c == '\n' || c == '\r') { + if (c != 0) { + back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + + /** + * Get the next value. The value can be a Boolean, Double, Integer, + * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. + * @throws JSONException If syntax error. + * + * @return An object. + */ + public Object nextValue() throws JSONException { + char c = nextClean(); + String s; + + switch (c) { + case '"': + case '\'': + return nextString(c); + case '{': + back(); + return new JSONObject(this); + case '[': + case '(': + back(); + return new JSONArray(this); + } + + /* + * Handle unquoted text. This could be the values true, false, or + * null, or it can be a number. An implementation (such as this one) + * is allowed to also accept non-standard forms. + * + * Accumulate characters until we reach the end of the text or a + * formatting character. + */ + + StringBuffer sb = new StringBuffer(); + while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { + sb.append(c); + c = next(); + } + back(); + + s = sb.toString().trim(); + if (s.equals("")) { + throw syntaxError("Missing value"); + } + return JSONObject.stringToValue(s); + } + + + /** + * Skip characters until the next character is the requested character. + * If the requested character is not found, no characters are skipped. + * @param to A character to skip to. + * @return The requested character, or zero if the requested character + * is not found. + */ + public char skipTo(char to) throws JSONException { + char c; + try { + int startIndex = this.index; + reader.mark(Integer.MAX_VALUE); + do { + c = next(); + if (c == 0) { + reader.reset(); + this.index = startIndex; + return c; + } + } while (c != to); + } catch (IOException exc) { + throw new JSONException(exc); + } + + back(); + return c; + } + + /** + * Make a JSONException to signal a syntax error. + * + * @param message The error message. + * @return A JSONException object, suitable for throwing + */ + public JSONException syntaxError(String message) { + return new JSONException(message + toString()); + } + + + /** + * Make a printable string of this JSONTokener. + * + * @return " at character [this.index]" + */ + @Override + public String toString() { + return " at character " + index; + } +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/json/JSONWriter.java b/ncomp-utils-java/src/main/java/org/json/JSONWriter.java new file mode 100644 index 0000000..875ab0e --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/JSONWriter.java @@ -0,0 +1,344 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +import java.io.IOException; +import java.io.Writer; + +/* +Copyright (c) 2006 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * JSONWriter provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONWriter can produce one JSON text. + * <p> + * A JSONWriter instance provides a <code>value</code> method for appending + * values to the + * text, and a <code>key</code> + * method for adding keys before values in objects. There are <code>array</code> + * and <code>endArray</code> methods that make and bound array values, and + * <code>object</code> and <code>endObject</code> methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting a cascade style. For example, <pre> + * new JSONWriter(myWriter) + * .object() + * .key("JSON") + * .value("Hello, World!") + * .endObject();</pre> which writes <pre> + * {"JSON":"Hello, World!"}</pre> + * <p> + * The first method called must be <code>array</code> or <code>object</code>. + * There are no methods for adding commas or colons. JSONWriter adds them for + * you. Objects and arrays can be nested up to 20 levels deep. + * <p> + * This can sometimes be easier than using a JSONObject to build a string. + * @author JSON.org + * @version 2008-09-18 + */ +public class JSONWriter { + private static final int maxdepth = 20; + + /** + * The comma flag determines if a comma should be output before the next + * value. + */ + private boolean comma; + + /** + * The current mode. Values: + * 'a' (array), + * 'd' (done), + * 'i' (initial), + * 'k' (key), + * 'o' (object). + */ + protected char mode; + + /** + * The object/array stack. + */ + private JSONObject stack[]; + + /** + * The stack top index. A value of 0 indicates that the stack is empty. + */ + private int top; + + /** + * The writer that will receive the output. + */ + protected Writer writer; + + /** + * Make a fresh JSONWriter. It can be used to build one JSON text. + */ + public JSONWriter(Writer w) { + this.comma = false; + this.mode = 'i'; + this.stack = new JSONObject[maxdepth]; + this.top = 0; + this.writer = w; + } + + /** + * Append a value. + * @param s A string value. + * @return this + * @throws JSONException If the value is out of sequence. + */ + private JSONWriter append(String s) throws JSONException { + if (s == null) { + throw new JSONException("Null pointer"); + } + if (this.mode == 'o' || this.mode == 'a') { + try { + if (this.comma && this.mode == 'a') { + this.writer.write(','); + } + this.writer.write(s); + } catch (IOException e) { + throw new JSONException(e); + } + if (this.mode == 'o') { + this.mode = 'k'; + } + this.comma = true; + return this; + } + throw new JSONException("Value out of sequence."); + } + + /** + * Begin appending a new array. All values until the balancing + * <code>endArray</code> will be appended to this array. The + * <code>endArray</code> method must be called to mark the array's end. + * @return this + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter array() throws JSONException { + if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { + this.push(null); + this.append("["); + this.comma = false; + return this; + } + throw new JSONException("Misplaced array."); + } + + /** + * End something. + * @param m Mode + * @param c Closing character + * @return this + * @throws JSONException If unbalanced. + */ + private JSONWriter end(char m, char c) throws JSONException { + if (this.mode != m) { + throw new JSONException(m == 'o' ? "Misplaced endObject." : + "Misplaced endArray."); + } + this.pop(m); + try { + this.writer.write(c); + } catch (IOException e) { + throw new JSONException(e); + } + this.comma = true; + return this; + } + + /** + * End an array. This method most be called to balance calls to + * <code>array</code>. + * @return this + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endArray() throws JSONException { + return this.end('a', ']'); + } + + /** + * End an object. This method most be called to balance calls to + * <code>object</code>. + * @return this + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endObject() throws JSONException { + return this.end('k', '}'); + } + + /** + * Append a key. The key will be associated with the next value. In an + * object, every value must be preceded by a key. + * @param s A key string. + * @return this + * @throws JSONException If the key is out of place. For example, keys + * do not belong in arrays or if the key is null. + */ + public JSONWriter key(String s) throws JSONException { + if (s == null) { + throw new JSONException("Null key."); + } + if (this.mode == 'k') { + try { + if (this.comma) { + this.writer.write(','); + } + stack[top - 1].putOnce(s, Boolean.TRUE); + this.writer.write(JSONObject.quote(s)); + this.writer.write(':'); + this.comma = false; + this.mode = 'o'; + return this; + } catch (IOException e) { + throw new JSONException(e); + } + } + throw new JSONException("Misplaced key."); + } + + + /** + * Begin appending a new object. All keys and values until the balancing + * <code>endObject</code> will be appended to this object. The + * <code>endObject</code> method must be called to mark the object's end. + * @return this + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter object() throws JSONException { + if (this.mode == 'i') { + this.mode = 'o'; + } + if (this.mode == 'o' || this.mode == 'a') { + this.append("{"); + this.push(new JSONObject()); + this.comma = false; + return this; + } + throw new JSONException("Misplaced object."); + + } + + + /** + * Pop an array or object scope. + * @param c The scope to close. + * @throws JSONException If nesting is wrong. + */ + private void pop(char c) throws JSONException { + if (this.top <= 0) { + throw new JSONException("Nesting error."); + } + char m = this.stack[this.top - 1] == null ? 'a' : 'k'; + if (m != c) { + throw new JSONException("Nesting error."); + } + this.top -= 1; + this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1] == null ? 'a' : 'k'; + } + + /** + * Push an array or object scope. + * @param c The scope to open. + * @throws JSONException If nesting is too deep. + */ + private void push(JSONObject jo) throws JSONException { + if (this.top >= maxdepth) { + throw new JSONException("Nesting too deep."); + } + this.stack[this.top] = jo; + this.mode = jo == null ? 'a' : 'k'; + this.top += 1; + } + + + /** + * Append either the value <code>true</code> or the value + * <code>false</code>. + * @param b A boolean. + * @return this + * @throws JSONException + */ + public JSONWriter value(boolean b) throws JSONException { + return this.append(b ? "true" : "false"); + } + + /** + * Append a double value. + * @param d A double. + * @return this + * @throws JSONException If the number is not finite. + */ + public JSONWriter value(double d) throws JSONException { + return this.value(new Double(d)); + } + + /** + * Append a long value. + * @param l A long. + * @return this + * @throws JSONException + */ + public JSONWriter value(long l) throws JSONException { + return this.append(Long.toString(l)); + } + + + /** + * Append an object value. + * @param o The object to append. It can be null, or a Boolean, Number, + * String, JSONObject, or JSONArray, or an object with a toJSONString() + * method. + * @return this + * @throws JSONException If the value is out of sequence. + */ + public JSONWriter value(Object o) throws JSONException { + return this.append(JSONObject.valueToString(o)); + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/Test.java b/ncomp-utils-java/src/main/java/org/json/Test.java new file mode 100644 index 0000000..4e87433 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/Test.java @@ -0,0 +1,650 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.io.StringWriter; + +/** + * Test class. This file is not formally a member of the org.json library. + * It is just a casual test tool. + */ +public class Test { + + /** + * Entry point. + * @param args + */ + public static void main(String args[]) { + Iterator<String> it; + JSONArray a; + JSONObject j; + JSONStringer jj; + String s; + +/** + * Obj is a typical class that implements JSONString. It also + * provides some beanie methods that can be used to + * construct a JSONObject. It also demonstrates constructing + * a JSONObject with an array of names. + */ + class Obj implements JSONString { + public String aString; + public double aNumber; + public boolean aBoolean; + + public Obj(String string, double n, boolean b) { + this.aString = string; + this.aNumber = n; + this.aBoolean = b; + } + + public double getNumber() { + return this.aNumber; + } + + public String getString() { + return this.aString; + } + + public boolean isBoolean() { + return this.aBoolean; + } + + public String getBENT() { + return "All uppercase key"; + } + + public String getX() { + return "x"; + } + + public String toJSONString() { + return "{" + JSONObject.quote(this.aString) + ":" + + JSONObject.doubleToString(this.aNumber) + "}"; + } + public String toString() { + return this.getString() + " " + this.getNumber() + " " + + this.isBoolean() + "." + this.getBENT() + " " + this.getX(); + } + } + + + Obj obj = new Obj("A beany object", 42, true); + + try { + j = XML.toJSONObject("<![CDATA[This is a collection of test patterns and examples for org.json.]]> Ignore the stuff past the end. "); + System.out.println(j.toString()); + + s = "{ \"list of lists\" : [ [1, 2, 3], [4, 5, 6], ] }"; + j = new JSONObject(s); + System.out.println(j.toString(4)); + System.out.println(XML.toString(j)); + + s = "<recipe name=\"bread\" prep_time=\"5 mins\" cook_time=\"3 hours\"> <title>Basic bread</title> <ingredient amount=\"8\" unit=\"dL\">Flour</ingredient> <ingredient amount=\"10\" unit=\"grams\">Yeast</ingredient> <ingredient amount=\"4\" unit=\"dL\" state=\"warm\">Water</ingredient> <ingredient amount=\"1\" unit=\"teaspoon\">Salt</ingredient> <instructions> <step>Mix all ingredients together.</step> <step>Knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again.</step> <step>Place in a bread baking tin.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Bake in the oven at 180(degrees)C for 30 minutes.</step> </instructions> </recipe> "; + j = XML.toJSONObject(s); + System.out.println(j.toString(4)); + System.out.println(); + + j = JSONML.toJSONObject(s); + System.out.println(j.toString()); + System.out.println(JSONML.toString(j)); + System.out.println(); + + a = JSONML.toJSONArray(s); + System.out.println(a.toString(4)); + System.out.println(JSONML.toString(a)); + System.out.println(); + + s = "<div id=\"demo\" class=\"JSONML\"><p>JSONML is a transformation between <b>JSON</b> and <b>XML</b> that preserves ordering of document features.</p><p>JSONML can work with JSON arrays or JSON objects.</p><p>Three<br/>little<br/>words</p></div>"; + j = JSONML.toJSONObject(s); + System.out.println(j.toString(4)); + System.out.println(JSONML.toString(j)); + System.out.println(); + + a = JSONML.toJSONArray(s); + System.out.println(a.toString(4)); + System.out.println(JSONML.toString(a)); + System.out.println(); + + s = "<person created=\"2006-11-11T19:23\" modified=\"2006-12-31T23:59\">\n <firstName>Robert</firstName>\n <lastName>Smith</lastName>\n <address type=\"home\">\n <street>12345 Sixth Ave</street>\n <city>Anytown</city>\n <state>CA</state>\n <postalCode>98765-4321</postalCode>\n </address>\n </person>"; + j = XML.toJSONObject(s); + System.out.println(j.toString(4)); + + j = new JSONObject(obj); + System.out.println(j.toString()); + + s = "{ \"entity\": { \"imageURL\": \"\", \"name\": \"IXXXXXXXXXXXXX\", \"id\": 12336, \"ratingCount\": null, \"averageRating\": null } }"; + j = new JSONObject(s); + System.out.println(j.toString(2)); + + jj = new JSONStringer(); + s = jj + .object() + .key("single") + .value("MARIE HAA'S") + .key("Johnny") + .value("MARIE HAA\\'S") + .key("foo") + .value("bar") + .key("baz") + .array() + .object() + .key("quux") + .value("Thanks, Josh!") + .endObject() + .endArray() + .key("obj keys") + .value(JSONObject.getNames(obj)) + .endObject() + .toString(); + System.out.println(s); + + System.out.println(new JSONStringer() + .object() + .key("a") + .array() + .array() + .array() + .value("b") + .endArray() + .endArray() + .endArray() + .endObject() + .toString()); + + jj = new JSONStringer(); + jj.array(); + jj.value(1); + jj.array(); + jj.value(null); + jj.array(); + jj.object(); + jj.key("empty-array").array().endArray(); + jj.key("answer").value(42); + jj.key("null").value(null); + jj.key("false").value(false); + jj.key("true").value(true); + jj.key("big").value(123456789e+88); + jj.key("small").value(123456789e-88); + jj.key("empty-object").object().endObject(); + jj.key("long"); + jj.value(9223372036854775807L); + jj.endObject(); + jj.value("two"); + jj.endArray(); + jj.value(true); + jj.endArray(); + jj.value(98.6); + jj.value(-100.0); + jj.object(); + jj.endObject(); + jj.object(); + jj.key("one"); + jj.value(1.00); + jj.endObject(); + jj.value(obj); + jj.endArray(); + System.out.println(jj.toString()); + + System.out.println(new JSONArray(jj.toString()).toString(4)); + + int ar[] = {1, 2, 3}; + JSONArray ja = new JSONArray(ar); + System.out.println(ja.toString()); + + String sa[] = {"aString", "aNumber", "aBoolean"}; + j = new JSONObject(obj, sa); + j.put("Testing JSONString interface", obj); + System.out.println(j.toString(4)); + + j = new JSONObject("{slashes: '///', closetag: '</script>', backslash:'\\\\', ei: {quotes: '\"\\''},eo: {a: '\"quoted\"', b:\"don't\"}, quotes: [\"'\", '\"']}"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = new JSONObject( + "{foo: [true, false,9876543210, 0.0, 1.00000001, 1.000000000001, 1.00000000000000001," + + " .00000000000000001, 2.00, 0.1, 2e100, -32,[],{}, \"string\"], " + + " to : null, op : 'Good'," + + "ten:10} postfix comment"); + j.put("String", "98.6"); + j.put("JSONObject", new JSONObject()); + j.put("JSONArray", new JSONArray()); + j.put("int", 57); + j.put("double", 123456789012345678901234567890.); + j.put("true", true); + j.put("false", false); + j.put("null", JSONObject.NULL); + j.put("bool", "true"); + j.put("zero", -0.0); + j.put("\\u2028", "\u2028"); + j.put("\\u2029", "\u2029"); + a = j.getJSONArray("foo"); + a.put(666); + a.put(2001.99); + a.put("so \"fine\"."); + a.put("so <fine>."); + a.put(true); + a.put(false); + a.put(new JSONArray()); + a.put(new JSONObject()); + j.put("keys", JSONObject.getNames(j)); + System.out.println(j.toString(4)); + System.out.println(XML.toString(j)); + + System.out.println("String: " + j.getDouble("String")); + System.out.println(" bool: " + j.getBoolean("bool")); + System.out.println(" to: " + j.getString("to")); + System.out.println(" true: " + j.getString("true")); + System.out.println(" foo: " + j.getJSONArray("foo")); + System.out.println(" op: " + j.getString("op")); + System.out.println(" ten: " + j.getInt("ten")); + System.out.println(" oops: " + j.optBoolean("oops")); + + s = "<xml one = 1 two=' \"2\" '><five></five>First \u0009<content><five></five> This is \"content\". <three> 3 </three>JSON does not preserve the sequencing of elements and contents.<three> III </three> <three> T H R E E</three><four/>Content text is an implied structure in XML. <six content=\"6\"/>JSON does not have implied structure:<seven>7</seven>everything is explicit.<![CDATA[CDATA blocks<are><supported>!]]></xml>"; + j = XML.toJSONObject(s); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + ja = JSONML.toJSONArray(s); + System.out.println(ja.toString(4)); + System.out.println(JSONML.toString(ja)); + System.out.println(""); + + s = "<xml do='0'>uno<a re='1' mi='2'>dos<b fa='3'/>tres<c>true</c>quatro</a>cinqo<d>seis<e/></d></xml>"; + ja = JSONML.toJSONArray(s); + System.out.println(ja.toString(4)); + System.out.println(JSONML.toString(ja)); + System.out.println(""); + + s = "<mapping><empty/> <class name = \"Customer\"> <field name = \"ID\" type = \"string\"> <bind-xml name=\"ID\" node=\"attribute\"/> </field> <field name = \"FirstName\" type = \"FirstName\"/> <field name = \"MI\" type = \"MI\"/> <field name = \"LastName\" type = \"LastName\"/> </class> <class name = \"FirstName\"> <field name = \"text\"> <bind-xml name = \"text\" node = \"text\"/> </field> </class> <class name = \"MI\"> <field name = \"text\"> <bind-xml name = \"text\" node = \"text\"/> </field> </class> <class name = \"LastName\"> <field name = \"text\"> <bind-xml name = \"text\" node = \"text\"/> </field> </class></mapping>"; + j = XML.toJSONObject(s); + + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + ja = JSONML.toJSONArray(s); + System.out.println(ja.toString(4)); + System.out.println(JSONML.toString(ja)); + System.out.println(""); + + j = XML.toJSONObject("<?xml version=\"1.0\" ?><Book Author=\"Anonymous\"><Title>Sample Book</Title><Chapter id=\"1\">This is chapter 1. It is not very long or interesting.</Chapter><Chapter id=\"2\">This is chapter 2. Although it is longer than chapter 1, it is not any more interesting.</Chapter></Book>"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = XML.toJSONObject("<!DOCTYPE bCard 'http://www.cs.caltech.edu/~adam/schemas/bCard'><bCard><?xml default bCard firstname = '' lastname = '' company = '' email = '' homepage = ''?><bCard firstname = 'Rohit' lastname = 'Khare' company = 'MCI' email = 'khare@mci.net' homepage = 'http://pest.w3.org/'/><bCard firstname = 'Adam' lastname = 'Rifkin' company = 'Caltech Infospheres Project' email = 'adam@cs.caltech.edu' homepage = 'http://www.cs.caltech.edu/~adam/'/></bCard>"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = XML.toJSONObject("<?xml version=\"1.0\"?><customer> <firstName> <text>Fred</text> </firstName> <ID>fbs0001</ID> <lastName> <text>Scerbo</text> </lastName> <MI> <text>B</text> </MI></customer>"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = XML.toJSONObject("<!ENTITY tp-address PUBLIC '-//ABC University::Special Collections Library//TEXT (titlepage: name and address)//EN' 'tpspcoll.sgm'><list type='simple'><head>Repository Address </head><item>Special Collections Library</item><item>ABC University</item><item>Main Library, 40 Circle Drive</item><item>Ourtown, Pennsylvania</item><item>17654 USA</item></list>"); + System.out.println(j.toString()); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = XML.toJSONObject("<test intertag status=ok><empty/>deluxe<blip sweet=true>&"toot"&toot;A</blip><x>eks</x><w>bonus</w><w>bonus2</w></test>"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = HTTP.toJSONObject("GET / HTTP/1.0\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*\nAccept-Language: en-us\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90; T312461; Q312461)\nHost: www.nokko.com\nConnection: keep-alive\nAccept-encoding: gzip, deflate\n"); + System.out.println(j.toString(2)); + System.out.println(HTTP.toString(j)); + System.out.println(""); + + j = HTTP.toJSONObject("HTTP/1.1 200 Oki Doki\nDate: Sun, 26 May 2002 17:38:52 GMT\nServer: Apache/1.3.23 (Unix) mod_perl/1.26\nKeep-Alive: timeout=15, max=100\nConnection: Keep-Alive\nTransfer-Encoding: chunked\nContent-Type: text/html\n"); + System.out.println(j.toString(2)); + System.out.println(HTTP.toString(j)); + System.out.println(""); + + j = new JSONObject("{nix: null, nux: false, null: 'null', 'Request-URI': '/', Method: 'GET', 'HTTP-Version': 'HTTP/1.0'}"); + System.out.println(j.toString(2)); + System.out.println("isNull: " + j.isNull("nix")); + System.out.println(" has: " + j.has("nix")); + System.out.println(XML.toString(j)); + System.out.println(HTTP.toString(j)); + System.out.println(""); + + j = XML.toJSONObject("<?xml version='1.0' encoding='UTF-8'?>"+"\n\n"+"<SOAP-ENV:Envelope"+ + " xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\""+ + " xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\""+ + " xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">"+ + "<SOAP-ENV:Body><ns1:doGoogleSearch"+ + " xmlns:ns1=\"urn:GoogleSearch\""+ + " SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"+ + "<key xsi:type=\"xsd:string\">GOOGLEKEY</key> <q"+ + " xsi:type=\"xsd:string\">'+search+'</q> <start"+ + " xsi:type=\"xsd:int\">0</start> <maxResults"+ + " xsi:type=\"xsd:int\">10</maxResults> <filter"+ + " xsi:type=\"xsd:boolean\">true</filter> <restrict"+ + " xsi:type=\"xsd:string\"></restrict> <safeSearch"+ + " xsi:type=\"xsd:boolean\">false</safeSearch> <lr"+ + " xsi:type=\"xsd:string\"></lr> <ie"+ + " xsi:type=\"xsd:string\">latin1</ie> <oe"+ + " xsi:type=\"xsd:string\">latin1</oe>"+ + "</ns1:doGoogleSearch>"+ + "</SOAP-ENV:Body></SOAP-ENV:Envelope>"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = new JSONObject("{Envelope: {Body: {\"ns1:doGoogleSearch\": {oe: \"latin1\", filter: true, q: \"'+search+'\", key: \"GOOGLEKEY\", maxResults: 10, \"SOAP-ENV:encodingStyle\": \"http://schemas.xmlsoap.org/soap/encoding/\", start: 0, ie: \"latin1\", safeSearch:false, \"xmlns:ns1\": \"urn:GoogleSearch\"}}}}"); + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + + j = CookieList.toJSONObject(" f%oo = b+l=ah ; o;n%40e = t.wo "); + System.out.println(j.toString(2)); + System.out.println(CookieList.toString(j)); + System.out.println(""); + + j = Cookie.toJSONObject("f%oo=blah; secure ;expires = April 24, 2002"); + System.out.println(j.toString(2)); + System.out.println(Cookie.toString(j)); + System.out.println(""); + + j = new JSONObject("{script: 'It is not allowed in HTML to send a close script tag in a string<script>because it confuses browsers</script>so we insert a backslash before the /'}"); + System.out.println(j.toString()); + System.out.println(""); + + JSONTokener jt = new JSONTokener("{op:'test', to:'session', pre:1}{op:'test', to:'session', pre:2}"); + j = new JSONObject(jt); + System.out.println(j.toString()); + System.out.println("pre: " + j.optInt("pre")); + int i = jt.skipTo('{'); + System.out.println(i); + j = new JSONObject(jt); + System.out.println(j.toString()); + System.out.println(""); + + a = CDL.toJSONArray("Comma delimited list test, '\"Strip\"Quotes', 'quote, comma', No quotes, 'Single Quotes', \"Double Quotes\"\n1,'2',\"3\"\n,'It is \"good,\"', \"It works.\"\n\n"); + + s = CDL.toString(a); + System.out.println(s); + System.out.println(""); + System.out.println(a.toString(4)); + System.out.println(""); + a = CDL.toJSONArray(s); + System.out.println(a.toString(4)); + System.out.println(""); + + a = new JSONArray(" [\"<escape>\", next is an implied null , , ok,] "); + System.out.println(a.toString()); + System.out.println(""); + System.out.println(XML.toString(a)); + System.out.println(""); + + j = new JSONObject("{ fun => with non-standard forms ; forgiving => This package can be used to parse formats that are similar to but not stricting conforming to JSON; why=To make it easier to migrate existing data to JSON,one = [[1.00]]; uno=[[{1=>1}]];'+':+6e66 ;pluses=+++;empty = '' , 'double':0.666,true: TRUE, false: FALSE, null=NULL;[true] = [[!,@;*]]; string=> o. k. ; \r oct=0666; hex=0x666; dec=666; o=0999; noh=0x0x}"); + System.out.println(j.toString(4)); + System.out.println(""); + if (j.getBoolean("true") && !j.getBoolean("false")) { + System.out.println("It's all good"); + } + + System.out.println(""); + j = new JSONObject(j, new String[]{"dec", "oct", "hex", "missing"}); + System.out.println(j.toString(4)); + + System.out.println(""); + System.out.println(new JSONStringer().array().value(a).value(j).endArray()); + + j = new JSONObject("{string: \"98.6\", long: 2147483648, int: 2147483647, longer: 9223372036854775807, double: 9223372036854775808}"); + System.out.println(j.toString(4)); + + System.out.println("\ngetInt"); + System.out.println("int " + j.getInt("int")); + System.out.println("long " + j.getInt("long")); + System.out.println("longer " + j.getInt("longer")); + System.out.println("double " + j.getInt("double")); + System.out.println("string " + j.getInt("string")); + + System.out.println("\ngetLong"); + System.out.println("int " + j.getLong("int")); + System.out.println("long " + j.getLong("long")); + System.out.println("longer " + j.getLong("longer")); + System.out.println("double " + j.getLong("double")); + System.out.println("string " + j.getLong("string")); + + System.out.println("\ngetDouble"); + System.out.println("int " + j.getDouble("int")); + System.out.println("long " + j.getDouble("long")); + System.out.println("longer " + j.getDouble("longer")); + System.out.println("double " + j.getDouble("double")); + System.out.println("string " + j.getDouble("string")); + + j.put("good sized", 9223372036854775807L); + System.out.println(j.toString(4)); + + a = new JSONArray("[2147483647, 2147483648, 9223372036854775807, 9223372036854775808]"); + System.out.println(a.toString(4)); + + System.out.println("\nKeys: "); + it = j.keys(); + while (it.hasNext()) { + s = it.next(); + System.out.println(s + ": " + j.getString(s)); + } + + + System.out.println("\naccumulate: "); + j = new JSONObject(); + j.accumulate("stooge", "Curly"); + j.accumulate("stooge", "Larry"); + j.accumulate("stooge", "Moe"); + a = j.getJSONArray("stooge"); + a.put(5, "Shemp"); + System.out.println(j.toString(4)); + + System.out.println("\nwrite:"); + System.out.println(j.write(new StringWriter())); + + s = "<xml empty><a></a><a>1</a><a>22</a><a>333</a></xml>"; + j = XML.toJSONObject(s); + System.out.println(j.toString(4)); + System.out.println(XML.toString(j)); + + s = "<book><chapter>Content of the first chapter</chapter><chapter>Content of the second chapter <chapter>Content of the first subchapter</chapter> <chapter>Content of the second subchapter</chapter></chapter><chapter>Third Chapter</chapter></book>"; + j = XML.toJSONObject(s); + System.out.println(j.toString(4)); + System.out.println(XML.toString(j)); + + a = JSONML.toJSONArray(s); + System.out.println(a.toString(4)); + System.out.println(JSONML.toString(a)); + + Collection<?> c = null; + Map<?, ?> m = null; + + j = new JSONObject(m); + a = new JSONArray(c); + j.append("stooge", "Joe DeRita"); + j.append("stooge", "Shemp"); + j.accumulate("stooges", "Curly"); + j.accumulate("stooges", "Larry"); + j.accumulate("stooges", "Moe"); + j.accumulate("stoogearray", j.get("stooges")); + j.put("map", m); + j.put("collection", c); + j.put("array", a); + a.put(m); + a.put(c); + System.out.println(j.toString(4)); + + s = "{plist=Apple; AnimalSmells = { pig = piggish; lamb = lambish; worm = wormy; }; AnimalSounds = { pig = oink; lamb = baa; worm = baa; Lisa = \"Why is the worm talking like a lamb?\" } ; AnimalColors = { pig = pink; lamb = black; worm = pink; } } "; + j = new JSONObject(s); + System.out.println(j.toString(4)); + + s = " (\"San Francisco\", \"New York\", \"Seoul\", \"London\", \"Seattle\", \"Shanghai\")"; + a = new JSONArray(s); + System.out.println(a.toString()); + + s = "<a ichi='1' ni='2'><b>The content of b</b> and <c san='3'>The content of c</c><d>do</d><e></e><d>re</d><f/><d>mi</d></a>"; + j = XML.toJSONObject(s); + + System.out.println(j.toString(2)); + System.out.println(XML.toString(j)); + System.out.println(""); + ja = JSONML.toJSONArray(s); + System.out.println(ja.toString(4)); + System.out.println(JSONML.toString(ja)); + System.out.println(""); + + + System.out.println("\nTesting Exceptions: "); + + System.out.print("Exception: "); + try { + a = new JSONArray(); + a.put(Double.NEGATIVE_INFINITY); + a.put(Double.NaN); + System.out.println(a.toString()); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + System.out.println(j.getDouble("stooge")); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + System.out.println(j.getDouble("howard")); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + System.out.println(j.put(null, "howard")); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + System.out.println(a.getDouble(0)); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + System.out.println(a.get(-1)); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + System.out.println(a.put(Double.NaN)); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + j = XML.toJSONObject("<a><b> "); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + j = XML.toJSONObject("<a></b> "); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + j = XML.toJSONObject("<a></a "); + } catch (Exception e) { + System.out.println(e); + } + System.out.print("Exception: "); + try { + ja = new JSONArray(new Object()); + System.out.println(ja.toString()); + } catch (Exception e) { + System.out.println(e); + } + + System.out.print("Exception: "); + try { + s = "[)"; + a = new JSONArray(s); + System.out.println(a.toString()); + } catch (Exception e) { + System.out.println(e); + } + + System.out.print("Exception: "); + try { + s = "<xml"; + ja = JSONML.toJSONArray(s); + System.out.println(ja.toString(4)); + } catch (Exception e) { + System.out.println(e); + } + + System.out.print("Exception: "); + try { + s = "<right></wrong>"; + ja = JSONML.toJSONArray(s); + System.out.println(ja.toString(4)); + } catch (Exception e) { + System.out.println(e); + } + + System.out.print("Exception: "); + try { + s = "{\"koda\": true, \"koda\": true}"; + j = new JSONObject(s); + System.out.println(j.toString(4)); + } catch (Exception e) { + System.out.println(e); + } + + System.out.print("Exception: "); + try { + jj = new JSONStringer(); + s = jj + .object() + .key("bosanda") + .value("MARIE HAA'S") + .key("bosanda") + .value("MARIE HAA\\'S") + .endObject() + .toString(); + System.out.println(j.toString(4)); + } catch (Exception e) { + System.out.println(e); + } + } catch (Exception e) { + System.out.println(e.toString()); + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/json/XML.java b/ncomp-utils-java/src/main/java/org/json/XML.java new file mode 100644 index 0000000..c3719af --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/XML.java @@ -0,0 +1,458 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Iterator; + + +/** + * This provides static methods to convert an XML text into a JSONObject, + * and to covert a JSONObject into an XML text. + * @author JSON.org + * @version 2008-10-14 + */ +public class XML { + + /** The Character '&'. */ + public static final Character AMP = new Character('&'); + + /** The Character '''. */ + public static final Character APOS = new Character('\''); + + /** The Character '!'. */ + public static final Character BANG = new Character('!'); + + /** The Character '='. */ + public static final Character EQ = new Character('='); + + /** The Character '>'. */ + public static final Character GT = new Character('>'); + + /** The Character '<'. */ + public static final Character LT = new Character('<'); + + /** The Character '?'. */ + public static final Character QUEST = new Character('?'); + + /** The Character '"'. */ + public static final Character QUOT = new Character('"'); + + /** The Character '/'. */ + public static final Character SLASH = new Character('/'); + + /** + * Replace special characters with XML escapes: + * <pre> + * & <small>(ampersand)</small> is replaced by &amp; + * < <small>(less than)</small> is replaced by &lt; + * > <small>(greater than)</small> is replaced by &gt; + * " <small>(double quote)</small> is replaced by &quot; + * </pre> + * @param string The string to be escaped. + * @return The escaped string. + */ + public static String escape(String string) { + StringBuffer sb = new StringBuffer(); + for (int i = 0, len = string.length(); i < len; i++) { + char c = string.charAt(i); + switch (c) { + case '&': + sb.append("&"); + break; + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '"': + sb.append("""); + break; + default: + sb.append(c); + } + } + return sb.toString(); + } + + /** + * Throw an exception if the string contains whitespace. + * Whitespace is not allowed in tagNames and attributes. + * @param string + * @throws JSONException + */ + public static void noSpace(String string) throws JSONException { + int i, length = string.length(); + if (length == 0) { + throw new JSONException("Empty string."); + } + for (i = 0; i < length; i += 1) { + if (Character.isWhitespace(string.charAt(i))) { + throw new JSONException("'" + string + + "' contains a space character."); + } + } + } + + /** + * Scan the content following the named tag, attaching it to the context. + * @param x The XMLTokener containing the source string. + * @param context The JSONObject that will include the new material. + * @param name The tag name. + * @return true if the close tag is processed. + * @throws JSONException + */ + private static boolean parse(XMLTokener x, JSONObject context, + String name) throws JSONException { + char c; + int i; + String n; + JSONObject o = null; + String s; + Object t; + +// Test for and skip past these forms: +// <!-- ... --> +// <! ... > +// <![ ... ]]> +// <? ... ?> +// Report errors for these forms: +// <> +// <= +// << + + t = x.nextToken(); + +// <! + + if (t == BANG) { + c = x.next(); + if (c == '-') { + if (x.next() == '-') { + x.skipPast("-->"); + return false; + } + x.back(); + } else if (c == '[') { + t = x.nextToken(); + if (t.equals("CDATA")) { + if (x.next() == '[') { + s = x.nextCDATA(); + if (s.length() > 0) { + context.accumulate("content", s); + } + return false; + } + } + throw x.syntaxError("Expected 'CDATA['"); + } + i = 1; + do { + t = x.nextMeta(); + if (t == null) { + throw x.syntaxError("Missing '>' after '<!'."); + } else if (t == LT) { + i += 1; + } else if (t == GT) { + i -= 1; + } + } while (i > 0); + return false; + } else if (t == QUEST) { + +// <? + + x.skipPast("?>"); + return false; + } else if (t == SLASH) { + +// Close tag </ + + t = x.nextToken(); + if (name == null) { + throw x.syntaxError("Mismatched close tag" + t); + } + if (!t.equals(name)) { + throw x.syntaxError("Mismatched " + name + " and " + t); + } + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped close tag"); + } + return true; + + } else if (t instanceof Character) { + throw x.syntaxError("Misshaped tag"); + +// Open tag < + + } else { + n = (String)t; + t = null; + o = new JSONObject(); + for (;;) { + if (t == null) { + t = x.nextToken(); + } + +// attribute = value + + if (t instanceof String) { + s = (String)t; + t = x.nextToken(); + if (t == EQ) { + t = x.nextToken(); + if (!(t instanceof String)) { + throw x.syntaxError("Missing value"); + } + o.accumulate(s, JSONObject.stringToValue((String)t)); + t = null; + } else { + o.accumulate(s, ""); + } + +// Empty tag <.../> + + } else if (t == SLASH) { + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped tag"); + } + context.accumulate(n, o); + return false; + +// Content, between <...> and </...> + + } else if (t == GT) { + for (;;) { + t = x.nextContent(); + if (t == null) { + if (n != null) { + throw x.syntaxError("Unclosed tag " + n); + } + return false; + } else if (t instanceof String) { + s = (String)t; + if (s.length() > 0) { + o.accumulate("content", JSONObject.stringToValue(s)); + } + +// Nested element + + } else if (t == LT) { + if (parse(x, o, n)) { + if (o.length() == 0) { + context.accumulate(n, ""); + } else if (o.length() == 1 && + o.opt("content") != null) { + context.accumulate(n, o.opt("content")); + } else { + context.accumulate(n, o); + } + return false; + } + } + } + } else { + throw x.syntaxError("Misshaped tag"); + } + } + } + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation + * because JSON is a data format and XML is a document format. XML uses + * elements, attributes, and content text, while JSON uses unordered + * collections of name/value pairs and arrays of values. JSON does not + * does not like to distinguish between elements and attributes. + * Sequences of similar elements are represented as JSONArrays. Content + * text may be placed in a "content" member. Comments, prologs, DTDs, and + * <code><[ [ ]]></code> are ignored. + * @param string The source string. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException + */ + public static JSONObject toJSONObject(String string) throws JSONException { + JSONObject o = new JSONObject(); + XMLTokener x = new XMLTokener(string); + while (x.more() && x.skipPast("<")) { + parse(x, o, null); + } + return o; + } + + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * @param o A JSONObject. + * @return A string. + * @throws JSONException + */ + public static String toString(Object o) throws JSONException { + return toString(o, null); + } + + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * @param o A JSONObject. + * @param tagName The optional name of the enclosing tag. + * @return A string. + * @throws JSONException + */ + public static String toString(Object o, String tagName) + throws JSONException { + StringBuffer b = new StringBuffer(); + int i; + JSONArray ja; + JSONObject jo; + String k; + Iterator<String> keys; + int len; + String s; + Object v; + if (o instanceof JSONObject) { + +// Emit <tagName> + + if (tagName != null) { + b.append('<'); + b.append(tagName); + b.append('>'); + } + +// Loop thru the keys. + + jo = (JSONObject)o; + keys = jo.keys(); + while (keys.hasNext()) { + k = keys.next().toString(); + v = jo.opt(k); + if (v == null) { + v = ""; + } + if (v instanceof String) { + s = (String)v; + } else { + s = null; + } + +// Emit content in body + + if (k.equals("content")) { + if (v instanceof JSONArray) { + ja = (JSONArray)v; + len = ja.length(); + for (i = 0; i < len; i += 1) { + if (i > 0) { + b.append('\n'); + } + b.append(escape(ja.get(i).toString())); + } + } else { + b.append(escape(v.toString())); + } + +// Emit an array of similar keys + + } else if (v instanceof JSONArray) { + ja = (JSONArray)v; + len = ja.length(); + for (i = 0; i < len; i += 1) { + v = ja.get(i); + if (v instanceof JSONArray) { + b.append('<'); + b.append(k); + b.append('>'); + b.append(toString(v)); + b.append("</"); + b.append(k); + b.append('>'); + } else { + b.append(toString(v, k)); + } + } + } else if (v.equals("")) { + b.append('<'); + b.append(k); + b.append("/>"); + +// Emit a new tag <k> + + } else { + b.append(toString(v, k)); + } + } + if (tagName != null) { + +// Emit the </tagname> close tag + + b.append("</"); + b.append(tagName); + b.append('>'); + } + return b.toString(); + +// XML does not have good support for arrays. If an array appears in a place +// where XML is lacking, synthesize an <array> element. + + } else if (o instanceof JSONArray) { + ja = (JSONArray)o; + len = ja.length(); + for (i = 0; i < len; ++i) { + v = ja.opt(i); + b.append(toString(v, (tagName == null) ? "array" : tagName)); + } + return b.toString(); + } else { + s = (o == null) ? "null" : escape(o.toString()); + return (tagName == null) ? "\"" + s + "\"" : + (s.length() == 0) ? "<" + tagName + "/>" : + "<" + tagName + ">" + s + "</" + tagName + ">"; + } + } +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/json/XMLTokener.java b/ncomp-utils-java/src/main/java/org/json/XMLTokener.java new file mode 100644 index 0000000..da1b0f2 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/XMLTokener.java @@ -0,0 +1,386 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/** + * The XMLTokener extends the JSONTokener to provide additional methods + * for the parsing of XML texts. + * @author JSON.org + * @version 2008-09-18 + */ +public class XMLTokener extends JSONTokener { + + + /** The table of entity values. It initially contains Character values for + * amp, apos, gt, lt, quot. + */ + public static final java.util.HashMap<String, Character> entity; + + static { + entity = new java.util.HashMap<String, Character>(8); + entity.put("amp", XML.AMP); + entity.put("apos", XML.APOS); + entity.put("gt", XML.GT); + entity.put("lt", XML.LT); + entity.put("quot", XML.QUOT); + } + + /** + * Construct an XMLTokener from a string. + * @param s A source string. + */ + public XMLTokener(String s) { + super(s); + } + + /** + * Get the text in the CDATA block. + * @return The string up to the <code>]]></code>. + * @throws JSONException If the <code>]]></code> is not found. + */ + public String nextCDATA() throws JSONException { + char c; + int i; + StringBuffer sb = new StringBuffer(); + for (;;) { + c = next(); + if (c == 0) { + throw syntaxError("Unclosed CDATA"); + } + sb.append(c); + i = sb.length() - 3; + if (i >= 0 && sb.charAt(i) == ']' && + sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') { + sb.setLength(i); + return sb.toString(); + } + } + } + + + /** + * Get the next XML outer token, trimming whitespace. There are two kinds + * of tokens: the '<' character which begins a markup tag, and the content + * text between markup tags. + * + * @return A string, or a '<' Character, or null if there is no more + * source text. + * @throws JSONException + */ + public Object nextContent() throws JSONException { + char c; + StringBuffer sb; + do { + c = next(); + } while (Character.isWhitespace(c)); + if (c == 0) { + return null; + } + if (c == '<') { + return XML.LT; + } + sb = new StringBuffer(); + for (;;) { + if (c == '<' || c == 0) { + back(); + return sb.toString().trim(); + } + if (c == '&') { + sb.append(nextEntity(c)); + } else { + sb.append(c); + } + c = next(); + } + } + + + /** + * Return the next entity. These entities are translated to Characters: + * <code>& ' > < "</code>. + * @param a An ampersand character. + * @return A Character or an entity String if the entity is not recognized. + * @throws JSONException If missing ';' in XML entity. + */ + public Object nextEntity(char a) throws JSONException { + StringBuffer sb = new StringBuffer(); + for (;;) { + char c = next(); + if (Character.isLetterOrDigit(c) || c == '#') { + sb.append(Character.toLowerCase(c)); + } else if (c == ';') { + break; + } else { + throw syntaxError("Missing ';' in XML entity: &" + sb); + } + } + String s = sb.toString(); + Object e = entity.get(s); + return e != null ? e : a + s + ";"; + } + + + /** + * Returns the next XML meta token. This is used for skipping over <!...> + * and <?...?> structures. + * @return Syntax characters (<code>< > / = ! ?</code>) are returned as + * Character, and strings and names are returned as Boolean. We don't care + * what the values actually are. + * @throws JSONException If a string is not properly closed or if the XML + * is badly structured. + */ + public Object nextMeta() throws JSONException { + char c; + char q; + do { + c = next(); + } while (Character.isWhitespace(c)); + switch (c) { + case 0: + throw syntaxError("Misshaped meta tag"); + case '<': + return XML.LT; + case '>': + return XML.GT; + case '/': + return XML.SLASH; + case '=': + return XML.EQ; + case '!': + return XML.BANG; + case '?': + return XML.QUEST; + case '"': + case '\'': + q = c; + for (;;) { + c = next(); + if (c == 0) { + throw syntaxError("Unterminated string"); + } + if (c == q) { + return Boolean.TRUE; + } + } + default: + for (;;) { + c = next(); + if (Character.isWhitespace(c)) { + return Boolean.TRUE; + } + switch (c) { + case 0: + case '<': + case '>': + case '/': + case '=': + case '!': + case '?': + case '"': + case '\'': + back(); + return Boolean.TRUE; + } + } + } + } + + + /** + * Get the next XML Token. These tokens are found inside of angle + * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it + * may be a string wrapped in single quotes or double quotes, or it may be a + * name. + * @return a String or a Character. + * @throws JSONException If the XML is not well formed. + */ + public Object nextToken() throws JSONException { + char c; + char q; + StringBuffer sb; + do { + c = next(); + } while (Character.isWhitespace(c)); + switch (c) { + case 0: + throw syntaxError("Misshaped element"); + case '<': + throw syntaxError("Misplaced '<'"); + case '>': + return XML.GT; + case '/': + return XML.SLASH; + case '=': + return XML.EQ; + case '!': + return XML.BANG; + case '?': + return XML.QUEST; + +// Quoted string + + case '"': + case '\'': + q = c; + sb = new StringBuffer(); + for (;;) { + c = next(); + if (c == 0) { + throw syntaxError("Unterminated string"); + } + if (c == q) { + return sb.toString(); + } + if (c == '&') { + sb.append(nextEntity(c)); + } else { + sb.append(c); + } + } + default: + +// Name + + sb = new StringBuffer(); + for (;;) { + sb.append(c); + c = next(); + if (Character.isWhitespace(c)) { + return sb.toString(); + } + switch (c) { + case 0: + return sb.toString(); + case '>': + case '/': + case '=': + case '!': + case '?': + case '[': + case ']': + back(); + return sb.toString(); + case '<': + case '"': + case '\'': + throw syntaxError("Bad character in a name"); + } + } + } + } + + + /** + * Skip characters until past the requested string. + * If it is not found, we are left at the end of the source with a result of false. + * @param to A string to skip past. + * @throws JSONException + */ + public boolean skipPast(String to) throws JSONException { + boolean b; + char c; + int i; + int j; + int offset = 0; + int n = to.length(); + char[] circle = new char[n]; + + /* + * First fill the circle buffer with as many characters as are in the + * to string. If we reach an early end, bail. + */ + + for (i = 0; i < n; i += 1) { + c = next(); + if (c == 0) { + return false; + } + circle[i] = c; + } + /* + * We will loop, possibly for all of the remaining characters. + */ + for (;;) { + j = offset; + b = true; + /* + * Compare the circle buffer with the to string. + */ + for (i = 0; i < n; i += 1) { + if (circle[j] != to.charAt(i)) { + b = false; + break; + } + j += 1; + if (j >= n) { + j -= n; + } + } + /* + * If we exit the loop with b intact, then victory is ours. + */ + if (b) { + return true; + } + /* + * Get the next character. If there isn't one, then defeat is ours. + */ + c = next(); + if (c == 0) { + return false; + } + /* + * Shove the character in the circle buffer and advance the + * circle offset. The offset is mod n. + */ + circle[offset] = c; + offset += 1; + if (offset >= n) { + offset -= n; + } + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/Base64.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/Base64.java new file mode 100644 index 0000000..23c38c2 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/Base64.java @@ -0,0 +1,626 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.util.Arrays; + +/** A very fast and memory efficient class to encode and decode to and from BASE64 in full accordance + * with RFC 2045.<br><br> + * On Windows XP sp1 with 1.4.2_04 and later ;), this encoder and decoder is about 10 times faster + * on small arrays (10 - 1000 bytes) and 2-3 times as fast on larger arrays (10000 - 1000000 bytes) + * compared to <code>sun.misc.Encoder()/Decoder()</code>.<br><br> + * + * On byte arrays the encoder is about 20% faster than Jakarta Commons Base64 Codec for encode and + * about 50% faster for decoding large arrays. This implementation is about twice as fast on very small + * arrays (< 30 bytes). If source/destination is a <code>String</code> this + * version is about three times as fast due to the fact that the Commons Codec result has to be recoded + * to a <code>String</code> from <code>byte[]</code>, which is very expensive.<br><br> + * + * This encode/decode algorithm doesn't create any temporary arrays as many other codecs do, it only + * allocates the resulting array. This produces less garbage and it is possible to handle arrays twice + * as large as algorithms that create a temporary array. (E.g. Jakarta Commons Codec). It is unknown + * whether Sun's <code>sun.misc.Encoder()/Decoder()</code> produce temporary arrays but since performance + * is quite low it probably does.<br><br> + * + * The encoder produces the same output as the Sun one except that the Sun's encoder appends + * a trailing line separator if the last character isn't a pad. Unclear why but it only adds to the + * length and is probably a side effect. Both are in conformance with RFC 2045 though.<br> + * Commons codec seem to always add a trailing line separator.<br><br> + * + * <b>Note!</b> + * The encode/decode method pairs (types) come in three versions with the <b>exact</b> same algorithm and + * thus a lot of code redundancy. This is to not create any temporary arrays for transcoding to/from different + * format types. The methods not used can simply be commented out.<br><br> + * + * There is also a "fast" version of all decode methods that works the same way as the normal ones, but + * har a few demands on the decoded input. Normally though, these fast verions should be used if the source if + * the input is known and it hasn't bee tampered with.<br><br> + * + * If you find the code useful or you find a bug, please send me a note at base64 @ miginfocom . com. + * + * Licence (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (base64 @ miginfocom . com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 2.2 + * @author Mikael Grev + * Date: 2004-aug-02 + * Time: 11:31:11 + */ + +public class Base64 +{ + + public static String encode64(byte[] a) { + return new String (encodeToChar(a,true)); + } + public static byte[] decode64(String s) { + return decode(s); + } + private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static final int[] IA = new int[256]; + static { + Arrays.fill(IA, -1); + for (int i = 0, iS = CA.length; i < iS; i++) + IA[CA[i]] = i; + IA['='] = 0; + } + + // **************************************************************************************** + // * char[] version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 <code>char[]</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static char[] encodeToChar(byte[] sArr, boolean lineSep) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new char[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + char[] dArr = new char[dLen]; + + // Encode even 24-bits + for (int s = 0, d = 0, cc = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = CA[(i >>> 18) & 0x3f]; + dArr[d++] = CA[(i >>> 12) & 0x3f]; + dArr[d++] = CA[(i >>> 6) & 0x3f]; + dArr[d++] = CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = CA[i >> 12]; + dArr[dLen - 3] = CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + /** Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. <code>null</code> or length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(char[] sArr) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new byte[0]; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[sArr[i]] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + int pad = 0; + for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;) + if (sArr[i] == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[sArr[s++]]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + return dArr; + } + + /** Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(char[])}. The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(char[] sArr) + { + // Check special case + int sLen = sArr.length; + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[sArr[sIx]] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[sArr[eIx]] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[sArr[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } + + // **************************************************************************************** + // * byte[] version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) + { + return encodeToByte(sArr, 0, sArr != null ? sArr.length : 0, lineSep); + } + + /** Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> an empty array will be returned. + * @param sOff The starting position in the bytes to convert. + * @param sLen The number of bytes to convert. If 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static byte[] encodeToByte(byte[] sArr, int sOff, int sLen, boolean lineSep) + { + // Check special case + if (sArr == null || sLen == 0) + return new byte[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + byte[] dArr = new byte[dLen]; + + // Encode even 24-bits + for (int s = sOff, d = 0, cc = 0; s < sOff + eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = (byte) CA[(i >>> 18) & 0x3f]; + dArr[d++] = (byte) CA[(i >>> 12) & 0x3f]; + dArr[d++] = (byte) CA[(i >>> 6) & 0x3f]; + dArr[d++] = (byte) CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't an even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[sOff + eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sOff + sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = (byte) CA[i >> 12]; + dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + /** Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(byte[] sArr) + { + return decode(sArr, 0, sArr.length); + } + + /** Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. <code>null</code> will throw an exception. + * @param sOff The starting position in the source array. + * @param sLen The number of bytes to decode from the source array. Length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(byte[] sArr, int sOff, int sLen) + { + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[sArr[sOff + i] & 0xff] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + int pad = 0; + for (int i = sLen; i > 1 && IA[sArr[sOff + --i] & 0xff] <= 0;) + if (sArr[sOff + i] == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[sArr[sOff + s++] & 0xff]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + + return dArr; + } + + + /** Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(byte[])}. The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(byte[] sArr) + { + // Check special case + int sLen = sArr.length; + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[sArr[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } + + // **************************************************************************************** + // * String version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static String encodeToString(byte[] sArr, boolean lineSep) + { + // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower. + return new String(encodeToChar(sArr, lineSep)); + } + + /** Decodes a BASE64 encoded <code>String</code>. All illegal characters will be ignored and can handle both strings with + * and without line separators.<br> + * <b>Note!</b> It can be up to about 2x the speed to call <code>decode(str.toCharArray())</code> instead. That + * will create a temporary array though. This version will use <code>str.charAt(i)</code> to iterate the string. + * @param str The source string. <code>null</code> or length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(String str) + { + // Check special case + int sLen = str != null ? str.length() : 0; + if (sLen == 0) + return new byte[0]; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[str.charAt(i)] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + // Count '=' at end + int pad = 0; + for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;) + if (str.charAt(i) == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[str.charAt(s++)]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + return dArr; + } + + /** Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(String)}. The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(String s) + { + // Check special case + int sLen = s.length(); + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[s.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/CryptoUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/CryptoUtils.java new file mode 100644 index 0000000..df35eb9 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/CryptoUtils.java @@ -0,0 +1,267 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import static org.openecomp.ncomp.utils.Base64.decode64; +import static org.openecomp.ncomp.utils.Base64.encode64; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.UUID; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.log4j.Logger; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class CryptoUtils { + public static final Logger logger = Logger.getLogger(CryptoUtils.class); + + public enum EncryptionType { + NONE, ENCRYPT, DECRYPT + }; + + public static String genNewKey() { + return UUID.randomUUID().toString(); + } + + public static String encryptPublic(String key, String value) { + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + KeySpec keySpec = new X509EncodedKeySpec(decode64(key)); + PublicKey key1 = keyFactory.generatePublic(keySpec); + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.ENCRYPT_MODE, key1); + return encode64(rsa.doFinal(value.getBytes())); + } catch (Exception e) { + throw new RuntimeException("encryption failed:" + e); + } + } + + public static String decryptPrivate(String key, String value) { + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + KeySpec keySpec = new PKCS8EncodedKeySpec(decode64(key)); + PrivateKey key1 = keyFactory.generatePrivate(keySpec); + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.DECRYPT_MODE, key1); + return new String(rsa.doFinal(decode64(value))); + } catch (Exception e) { + throw new RuntimeException("encryption failed:" + e); + } + + } + + public static InputStream getInputStream(final InputStream in, final EncryptionType type, final String key) { + final Cipher aes; + logger.debug("crypto in stream:" + PropertyUtil.replaceForLogForcingProtection(type) + " " + PropertyUtil.replaceForLogForcingProtection(key)); + try { + aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); + switch (type) { + case DECRYPT: + aes.init(Cipher.DECRYPT_MODE, string2key(key)); + break; + case ENCRYPT: + aes.init(Cipher.ENCRYPT_MODE, string2key(key)); + break; + default: + break; + } + return new CipherInputStream(in, aes); + } catch (Exception e) { + throw new RuntimeException("encryption failed:" + e); + } + } + + public static OutputStream getOutputStream(final OutputStream out, final EncryptionType type, final String key) { + final Cipher aes; + logger.debug("crypto out stream:" + type + " " + key); + try { + aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); + switch (type) { + case DECRYPT: + aes.init(Cipher.DECRYPT_MODE, string2key(key)); + break; + case ENCRYPT: + aes.init(Cipher.ENCRYPT_MODE, string2key(key)); + break; + default: + break; + } + return new CipherOutputStream(out, aes); + } catch (Exception e) { + throw new RuntimeException("encryption failed:" + e); + } + } + + private static SecretKeySpec string2key(String key) throws NoSuchAlgorithmException { + MessageDigest digest = MessageDigest.getInstance("SHA"); + digest.update(key.getBytes()); + return new SecretKeySpec(digest.digest(), 0, 16, "AES"); + } + + public static String getKey(String fileName) { + ByteArrayOutputStream o = new ByteArrayOutputStream(); + InputStream in = null; + try { + in = new FileInputStream(FileUtils.safeFileName(fileName)); + FileUtils.copyStream(in, o); + } catch (IOException e) { + throw new RuntimeException("getKey failed:" + e); + } finally { + if (in != null) + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return o.toString(); + } + + @SuppressWarnings("resource") + public static void main(String[] args) throws Exception { + String command = "createKeyPair"; + if (args.length > 0) + command = args[0]; + if (command.equals("createKeyPair")) { + String key = (args.length <= 1) ? "key" : args[1]; + createKeyPair(key); + } + if (command.equals("file")) { + EncryptionType t = EncryptionType.valueOf(args[1].toUpperCase()); + InputStream in = new FileInputStream(FileUtils.safeFileName(args[2])); + OutputStream out = new FileOutputStream(FileUtils.safeFileName(args[3])); + try { + in = getInputStream(in, t, args[4]); + FileUtils.copyStream(in, out); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + } + } + + public static String digest(byte[] a) throws NoSuchAlgorithmException { + MessageDigest digest = MessageDigest.getInstance("SHA"); + return encode64(digest.digest(a)); + } + + public static void createKeyPair(String key) throws Exception { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + PublicKey publicKey = keyPair.getPublic(); + PrivateKey privateKey = keyPair.getPrivate(); + FileOutputStream out = null; + try { + out = new FileOutputStream(FileUtils.safeFileName(key + ".private")); + out.write(encode64(privateKey.getEncoded()).getBytes()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (out != null) + out.close(); + } + try { + out = new FileOutputStream(FileUtils.safeFileName(key + ".public")); + out.write(encode64(publicKey.getEncoded()).getBytes()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (out != null) + out.close(); + } + System.out.println("Create private file: " + key + ".private " + digest(privateKey.getEncoded())); + System.out.println("Create public file: " + key + ".public " + digest(publicKey.getEncoded())); + } + + public static String encrypt(String key, String value) { + logger.debug("encrypt: " + key + " " + value); + try { + Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); + aes.init(Cipher.ENCRYPT_MODE, string2key(key)); + return encode64(aes.doFinal(value.getBytes())); + } catch (Exception e) { + throw new RuntimeException("encrypt failed:" + e); + } + } + + public static String decrypt(String key, String value) { + logger.debug("decrypt: " + key + " " + value); + try { + Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); + aes.init(Cipher.DECRYPT_MODE, string2key(key)); + return new String(aes.doFinal(decode64(value))); + } catch (Exception e) { + throw new RuntimeException("decrypt failed:" + e); + } + } + + public static String digestFile(String filename) throws Exception { + InputStream fis = null; + MessageDigest complete = null; + try { + fis = new FileInputStream(FileUtils.safeFileName(filename)); + byte[] buffer = new byte[1024]; + complete = MessageDigest.getInstance("MD5"); + int numRead; + do { + numRead = fis.read(buffer); + if (numRead > 0) { + complete.update(buffer, 0, numRead); + } + } while (numRead != -1); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (fis != null) + fis.close(); + } + return encode64(complete.digest()); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/CryptoUtilsTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/CryptoUtilsTest.java new file mode 100644 index 0000000..ac1c6f3 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/CryptoUtilsTest.java @@ -0,0 +1,160 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import static org.openecomp.ncomp.utils.Base64.decode64; +import static org.openecomp.ncomp.utils.CryptoUtils.createKeyPair; +import static org.openecomp.ncomp.utils.CryptoUtils.decrypt; +import static org.openecomp.ncomp.utils.CryptoUtils.decryptPrivate; +import static org.openecomp.ncomp.utils.CryptoUtils.digest; +import static org.openecomp.ncomp.utils.CryptoUtils.digestFile; +import static org.openecomp.ncomp.utils.CryptoUtils.encrypt; +import static org.openecomp.ncomp.utils.CryptoUtils.encryptPublic; +import static org.openecomp.ncomp.utils.CryptoUtils.getInputStream; +import static org.openecomp.ncomp.utils.CryptoUtils.getKey; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.spec.SecretKeySpec; + +import junit.framework.TestCase; + +import org.openecomp.ncomp.utils.CryptoUtils.EncryptionType; +import org.openecomp.ncomp.webservice.utils.FileUtils; + + + +public class CryptoUtilsTest extends TestCase { + String key = "dafdfkj"; + String value = "Hello"; + + public void test_encrypt() { + assertEquals(value, decrypt(key,encrypt(key, value))); + } + public void test_streams() throws Exception { + Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); + MessageDigest digest = MessageDigest.getInstance("SHA"); + digest.update("foobar".getBytes()); + SecretKeySpec key1 = new SecretKeySpec(digest.digest(), 0, 16, "AES"); + aes.init(Cipher.ENCRYPT_MODE, key1); + InputStream in = new FileInputStream("test/Test.txt"); + in = new CipherInputStream(in, aes); + FileOutputStream out = new FileOutputStream("test/Encrypted.txt"); + try { + FileUtils.copyStream(in, out); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + aes.init(Cipher.DECRYPT_MODE, key1); + in = new FileInputStream("test/Encrypted.txt"); + in = new CipherInputStream(in, aes); + out = new FileOutputStream("test/Decrypted.txt"); + try { + FileUtils.copyStream(in, out); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + assertEquals(digestFile("test/Test.txt"), digestFile("test/Decrypted.txt")); + } + @SuppressWarnings("resource") + public void test_streams_2() throws Exception { + InputStream in = new FileInputStream("test/Test.txt"); + in = getInputStream(in, EncryptionType.ENCRYPT, key); + FileOutputStream out = new FileOutputStream("test/Encrypted.txt"); + try { + FileUtils.copyStream(in, out); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + in = new FileInputStream("test/Encrypted.txt"); + in = getInputStream(in, EncryptionType.DECRYPT, key); + out = new FileOutputStream("test/Decrypted.txt"); + try { + FileUtils.copyStream(in, out); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + assertEquals(digestFile("test/Test.txt"), digestFile("test/Decrypted.txt")); + } + public void test_public_key() throws Exception { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); + byte[] ciphertext = rsa.doFinal(value.getBytes()); + rsa.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); + byte[] text = rsa.doFinal(ciphertext); + assertEquals(value, new String(text)); + } + + public void test_public_key_1() throws Exception { + createKeyPair("test/key"); + String publicKey = getKey("test/key.public"); + System.out.println(digest(decode64(publicKey))); + String privateKey = getKey("test/key.private"); + System.out.println(digest(decode64(privateKey))); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey k1 = keyFactory.generatePublic(new X509EncodedKeySpec(decode64(publicKey))); + PrivateKey k2 = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(decode64(privateKey))); + Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + rsa.init(Cipher.ENCRYPT_MODE, k1); + byte[] ciphertext = rsa.doFinal(value.getBytes()); + rsa.init(Cipher.DECRYPT_MODE, k2); + byte[] text = rsa.doFinal(ciphertext); + assertEquals(value, new String(text)); + + } + + public void test_public_key_2() throws Exception { + createKeyPair("test/key"); + String publicKey = getKey("test/key.public"); + System.out.println(digest(decode64(publicKey))); + String privateKey = getKey("test/key.private"); + System.out.println(digest(decode64(privateKey))); + assertEquals(value, decryptPrivate(privateKey,encryptPublic(publicKey, value))); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/DiffUtil.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/DiffUtil.java new file mode 100644 index 0000000..de53157 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/DiffUtil.java @@ -0,0 +1,915 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import junit.framework.Assert; + +public class DiffUtil { + /** + * A {@link Comparator}-like interface for {@link DiffUtil#editDist(List, List, DiffEquals)} + * and {@link DiffUtil#editScript(List, List, DiffEquals)}. Contains two boolean + * methods, {@link #equals(Object, Object)} and {@link #canChange(Object, Object)}. + * + * {@link #equals(Object, Object)} determines if two items are equal, and + * {@link #canChange(Object, Object)} determines if for two + * non-equal items a and b, a can be changed into b. + * + * @param <T> the type being compared + */ + public static interface DiffEquals<T> { + /** + * @param a + * @param b + * @return {@code true} if a equals b, {@code false} otherwise + */ + boolean equals(T a, T b); + /** + * @param a + * @param b + * @return {@code true} if a can be changed to b, {@code false} otherwise + */ + boolean canChange(T a, T b); + } + /** + * A class implementing {@link DiffEquals} based on a {@link Comparator} comp. + * {@code equals(a,b)} returns {@code (comp.compare(a,b)==0)}, and + * {@code canChange(a,b)} returns {@code true}. + * + * @param <T> the type being compared + */ + public static class DiffEqualsFromCompare<T> implements DiffEquals<T> { + private final Comparator<T> comp; + public DiffEqualsFromCompare(Comparator<T> comp) { + this.comp = comp; + } + public boolean equals (T a, T b) { + return (comp.compare(a,b) == 0); + } + public boolean canChange (T a, T b) { + return true; + } + } + /** + * A class implementing {@link DiffEquals} based on {@link Object#equals(Object)}. + * {@code equals(a,b)} returns {@code (a.equals(b))}, and + * {@code canChange(a,b)} returns {@code true}. + * + * @param <T> the type being compared + */ + public static class DiffEqualsDefault<T> implements DiffEquals<T> { + public boolean equals (T a, T b) { + return (a.equals(b)); + } + public boolean canChange (T a, T b) { + return true; + } + } + /** + * A class implementing {@link DiffEquals} based on {@link Object#equals(Object)}, + * but not allowing changes. + * {@code equals(a,b)} returns {@code (a.equals(b))}, and + * {@code canChange(a,b)} returns {@code false}. + * + * @param <T> the type being compared + */ + public static class DiffEqualsNoChange<T> implements DiffEquals<T> { + public boolean equals (T a, T b) { + return (a.equals(b)); + } + public boolean canChange (T a, T b) { + return false; + } + } + /** + * A class implementing {@link DiffEquals} based on two {@link Comparator}s, comp and change. + * {@code equals(a,b)} returns {@code (comp.compare(a,b)==0)}, and + * {@code canChange(a,b)} returns {@code (change.compare(a,b)==0)}. + * + * @param <T> the type being compared + */ + public static class DiffEqualsCompareChange<T> implements DiffEquals<T> { + private final Comparator<T> comp; + private final Comparator<T> change; + public DiffEqualsCompareChange(Comparator<T> comp, Comparator<T> change) { + this.comp = comp; + this.change = change; + } + public boolean equals (T a, T b) { + return (comp.compare(a,b) == 0); + } + public boolean canChange (T a, T b) { + return (change.compare(a, b) == 0); + } + } + + /** + * A {@link Comparator}-like interface for {@link DiffUtil#editScriptSorted(Collection, Collection, DiffCompare)}. + * Contains an int method {@link #compare(Object, Object)} and + * a boolean method {@link #canChange(Object, Object)}. + * <p> + * {@link #compare(Object, Object)} gives the ordering of the items in the list, + * {@link #canChange(Object, Object)} indicates items with compare()!=0 can be changed. + * <p> + * These should be compatible. That is, items that are in the same equivalence class defined by {@link #canChange(Object, Object)} + * should be contiguous in the order defined by {@link #compare(Object, Object)}. + * + * @param <T> the type being compared + */ + public static interface DiffCompare<T> { + /** + * @param a + * @param b + * @return {@code < 0} if a is less than b, {@code > 0} if a is greater than b, and {@code 0} if a equals b + */ + int compare(T a, T b); + /** + * @param a + * @param b + * @return {@code true} if a can be changed to b, {@code false} otherwise + */ + boolean canChange(T a, T b); + } + /** + * A class implementing {@link DiffCompare} based on a {@link Comparator} comp. + * {@code compare(a,b)} returns {@code comp.compare(a,b)}, and + * {@code canChange(a,b)} returns {@code true}. + * + * @param <T> the type being compared + */ + public static class DiffComparator<T> implements DiffCompare<T> { + private final Comparator<T> comp; + public DiffComparator(Comparator<T> comp) { + this.comp = comp; + } + public int compare (T a, T b) { + return comp.compare(a,b); + } + public boolean canChange (T a, T b) { + return true; + } + } + /** + * A class implementing {@link DiffCompare} based on {@link Comparable#compareTo(Object)}. + * {@code compare(a,b)} returns {@code (a.compareTo(b))}, and + * {@code canChange(a,b)} returns {@code true}. + * + * @param <T> the type being compared + */ + public static class DiffComparable<T extends Comparable<T>> implements DiffCompare<T> { + public int compare (T a, T b) { + return (a.compareTo(b)); + } + public boolean canChange (T a, T b) { + return true; + } + } + /** + * A class implementing {@link DiffCompare} based on two {@link Comparator}s, comp and change. + * {@code compare(a,b)} returns {@code comp.compare(a,b)}, and + * {@code canChange(a,b)} returns {@code (change.compare(a,b)==0)}. + * + * @param <T> the type being compared + */ + public static class DiffCompareChange<T> implements DiffCompare<T> { + private final Comparator<T> comp; + private final Comparator<T> change; + public DiffCompareChange(Comparator<T> comp, Comparator<T> change) { + this.comp = comp; + this.change = change; + } + public int compare (T a, T b) { + return comp.compare(a,b); + } + public boolean canChange (T a, T b) { + return (change.compare(a, b) == 0); + } + } + + /** + * + * An enumeration of edit types. + * + */ + public static enum EditType { + /** + * Change A to B. Will only be used if {@code canChange(a,b)}. + */ + ChangeAtoB (0, "Change A to B"), + /** + * Only in A. An item that is in A but not in B (that is, it was inserted into A, or deleted from B). + */ + OnlyInA (1, "Only in A"), + /** + * Only in B. An item that is in B but not in A (that is, it was inserted into B, or deleted from A). + */ + OnlyInB (2, "Only in B"), + /** + * Replace A with B. Only generated by {@link DiffUtil#mergeReplaces(Collection)}, + * and will only be used if {@code canChange(a,b)==false}. + */ + ReplaceAwithB (3, "Replace A with B"); + + private final int value; + private final String name; + private EditType(int value, String name) { + this.value = value; + this.name = name; + } + public String toString() { + return name; + } + public int value() { + return value; + } + } + + /** + * + * A description of an edit between two lists + * + * @param <T> the type of elements in the lists + */ + public static class Edit<T> { + /** + * The {@link #EditType type} of edit + */ + public final EditType type; + /** + * The index of the affected entry in the "a" list. Will be -1 if {@link #type} is {@link EditType#OnlyInB} + */ + public final int a_index; + /** + * The index of the affected entry in the "b" list. Will be -1 if {@link #type} is {@link EditType#OnlyInA} + */ + public final int b_index; + /** + * The value of the affected entry in the "a" list. Will be {@code null} if {@link #type} is {@link EditType#OnlyInB} + */ + public final T a_value; + /** + * The value of the affected entry in the "b" list. Will be {@code null} if {@link #type} is {@link EditType#OnlyInA} + */ + public final T b_value; + public Edit (EditType type, int a_index, int b_index, T a_value, T b_value) { + this.type = type; + this.a_index = a_index; + this.b_index = b_index; + this.a_value = a_value; + this.b_value = b_value; + } + public boolean equals (Object o) { + if (o instanceof Edit<?>) { + Edit<?> a = (Edit<?>) o; + if (!type.equals(a.type)) return false; + if (a_index != a.a_index) return false; + if (b_index != a.b_index) return false; + if (a_value == null) { + if (a.a_value != null) return false; + } else { + if (!a_value.equals(a.a_value)) return false; + } + if (b_value == null) { + if (a.b_value != null) return false; + } else { + if (!b_value.equals(a.b_value)) return false; + } + return true; + } else { + return false; + } + } + @Override + public String toString() { + switch (type) { + case ChangeAtoB: + return type.toString()+"/"+a_value.toString()+"@"+a_index+"/"+b_value.toString()+"@"+b_index; + case OnlyInA: + return type.toString()+"/"+a_value.toString()+"@"+a_index; + case OnlyInB: + return type.toString()+"/"+b_value.toString()+"@"+b_index; + case ReplaceAwithB: + return type.toString()+"/"+a_value.toString()+"@"+a_index+"/"+b_value.toString()+"@"+b_index; + default: + return type.toString(); + } + } + } + + private static class DiagEntry { + public final int dist; + public final int loc; + public final int dir; // 0 = NW, -1 = W, 1 = N + public final int prev_loc; + public DiagEntry(int dist, int loc, int dir, int prev_loc) { + this.dist = dist; + this.loc = loc; + this.dir = dir; + this.prev_loc = prev_loc; + } + } + private static class DistWork<T> { + private final List<T> a; + private final List<T> b; + private final DiffEquals<? super T> comp; + // entry (i,j) ==> diags(i-j) loc i + // diags(d) loc l ==> entry (l, l-d) + private final ArrayList<ArrayList<DiagEntry>> diags; + public DistWork(List<T> a, List<T> b, DiffEquals<? super T> comp) { + this.a = a; + this.b = b; + this.comp = comp; + diags = new ArrayList<ArrayList<DiagEntry>>(); + } + private int diag2entry(int k) { + if (k>=0) return 2*k; + else return (-2*k-1); + } + private ArrayList<DiagEntry> diag2list(int k) { + int e = diag2entry(k); + if (e >= diags.size()) return null; + return diags.get(e); + } + private int last_d_idx(int k) { + ArrayList<DiagEntry> l = diag2list(k); + if (l == null) return -1; + return l.size() - 1; + } + private DiagEntry last_d_entry(int k) { + ArrayList<DiagEntry> l = diag2list(k); + if (l == null) return null; + return l.get(l.size()-1); + } + private DiagEntry diag_entry(int k, int idx) { + ArrayList<DiagEntry> l = diag2list(k); + if (l == null) return null; + return l.get(idx); + } + private int last_d(int k) { + ArrayList<DiagEntry> l = diag2list(k); + if (l == null || l.isEmpty()) return /* (k <= 0) ? 0 : k */ -1; + return l.get(l.size()-1).loc; + } + private void last_d_add (int k, int dist, int loc, int dir, int prev_loc) { + last_d_add (k, new DiagEntry(dist, loc, dir, prev_loc)); + } + private void last_d_add (int k, DiagEntry d) { + int e = diag2entry(k); + while (e >= diags.size()) diags.add(new ArrayList<DiagEntry>()); + diags.get(e).add(d); + } + private DiagEntry find_last_d (int k, int d) { + int prev_loc; + int row; + int dir; + + if (k == d || (k != -d && last_d(k-1) >= last_d(k+1))) { + prev_loc = last_d_idx(k-1); + row = last_d(k-1)+1; + dir = -1; + } else { + prev_loc = last_d_idx(k+1); + row = last_d(k+1); + dir = +1; + } + if (last_d(k) >= row && k != d && -k != d && comp.canChange(a.get(row),b.get(row-k))) { + prev_loc = last_d_idx(k); + row = last_d(k)+1; + dir = 0; + } + int col = row - k; + while (row < a.size() && col < b.size() && comp.equals(a.get(row),b.get(col))) { + row++; + col++; + } + return new DiagEntry(d, row, dir, prev_loc); + } + + public int dist () { + int i=0; + while (i < a.size() && i < b.size() && comp.equals(a.get(i), b.get(i))) { + i++; + } + last_d_add (0, 0, i, 0, -1); + int target = a.size() - b.size(); + int upper = (i == a.size()) ? -1 : 1; + int lower = (i == b.size()) ? 1 : -1; + int maxDist = 0; + ArrayList<DiagEntry> new_entries = new ArrayList<DiagEntry>(); + while (last_d(target) < a.size()) { + maxDist++; + new_entries.clear(); + for (int k = lower; k <= upper; k++) { + DiagEntry e = find_last_d(k, maxDist); + new_entries.add(e); + } + int new_lower = lower-1; + int new_upper = upper+1; + for (int k = lower; k <= upper; k++) { + DiagEntry e = new_entries.get(k-lower); + last_d_add (k, e); + if (e.loc >= a.size() && k <= new_upper) new_upper = k-1; + if (e.loc - k >= b.size() && k >= new_lower) new_lower = k+1; + } + lower = new_lower; + upper = new_upper; + } + DiagEntry e = last_d_entry(target); + if (e == null) return (target >= 0) ? target : -target; + return e.dist; + } + public List<Edit<T>> script() { + int d = dist(); + LinkedList<Edit<T>> l = new LinkedList<Edit<T>>(); + if (a.size() == 0) { + Assert.assertEquals(d, b.size()); + for (int i=0; i<b.size(); i++) { + l.addFirst(new Edit<T>(EditType.OnlyInB, -1, i, null, b.get(i))); + } + return l; + } + if (b.size() == 0) { + Assert.assertEquals(d, a.size()); + for (int i=0; i<a.size(); i++) { + l.addFirst(new Edit<T>(EditType.OnlyInA, i, -1, a.get(i), null)); + } + return l; + } + int k = a.size() - b.size(); + while (d > 0) { + int idx = d - ((k >= 0) ? k : -k); + DiagEntry e = diag_entry (k, idx); + Assert.assertNotNull(e); + Assert.assertEquals(e.dist, d); + int new_k = k + e.dir; + int new_idx = (d-1) - ((new_k >= 0) ? new_k : -new_k); + DiagEntry new_e = diag_entry (new_k, new_idx); + Assert.assertEquals(e.prev_loc, new_idx); + int aloc = new_e.loc; + int bloc = aloc - new_k; + switch (e.dir) { + case 0: + l.addFirst(new Edit<T>(EditType.ChangeAtoB, aloc, bloc, a.get(aloc), b.get(bloc))); + break; + case -1: + l.addFirst(new Edit<T>(EditType.OnlyInA, aloc, -1, a.get(aloc), null)); + break; + case 1: + l.addFirst(new Edit<T>(EditType.OnlyInB, -1, bloc, null, b.get(bloc))); + break; + default: throw new RuntimeException("Unexpected dir " + e.dir); + } + d--; + k = new_k; + } + return l; + } + @SuppressWarnings("unused") + public void dumpDiags() { + for (int i=0; i<diags.size(); i++) { + int d = (i%2 == 0) ? (i/2) : (-(i+1)/2); + System.out.print("diag " + d + ":"); + for (DiagEntry e : diags.get(i)) { + System.out.print(" " + e.dist + "," + e.loc + "," + e.dir + "," + e.prev_loc); + } + System.out.println(); + } + } + public void dumpStats(String msg) { + int lcnt = 0; + int setcnt = 0; + for (ArrayList<DiagEntry> diag : diags) { + if (!diag.isEmpty()) { + lcnt++; + setcnt += diag.size(); + } + } + System.out.print("Dist diag stats:"); + if (msg != null) System.out.print(" "+msg); + System.out.println(" size=" + diags.size() + + " diags=" + lcnt + " entries=" + setcnt); +// dumpDiags(); + } + } + + private static class DistWorkSorted<T> { + private final Iterator<T> a_iter; + private int a_idx; + private final Iterator<T> b_iter; + private int b_idx; + private final DiffCompare<T> comp; + private static class ValIdx<T> { + public final T val; + public final int idx; + public ValIdx(T val, int idx) { + this.val = val; + this.idx = idx; + } + } + public DistWorkSorted(Collection<T> a, Collection<T> b, DiffCompare<T> comp) { + this.a_iter = a.iterator(); + this.b_iter = b.iterator(); + this.comp = comp; + } + private void flushLists (T val, LinkedList<ValIdx<T>> a_list, LinkedList<ValIdx<T>> b_list, List<Edit<T>> ret) { + if ((!a_list.isEmpty() && !comp.canChange(val, a_list.getFirst().val)) || + (!b_list.isEmpty() && !comp.canChange(val, b_list.getFirst().val))) { + flushLists(a_list, b_list, ret); + } + } + private void flushLists (LinkedList<ValIdx<T>> a_list, LinkedList<ValIdx<T>> b_list, List<Edit<T>> ret) { + while (!a_list.isEmpty() && !b_list.isEmpty()) { + ValIdx<T> a = a_list.removeFirst(); + ValIdx<T> b = b_list.removeFirst(); + ret.add(new Edit<T>(EditType.ChangeAtoB, a.idx, b.idx, a.val, b.val)); + } + while (!a_list.isEmpty()) { + ValIdx<T> a = a_list.removeFirst(); + ret.add(new Edit<T>(EditType.OnlyInA, a.idx, -1, a.val, null)); + } + while (!b_list.isEmpty()) { + ValIdx<T> b = b_list.removeFirst(); + ret.add(new Edit<T>(EditType.OnlyInB, -1, b.idx, null, b.val)); + } + } + public List<Edit<T>> script () { + List<Edit<T>> ret = new ArrayList<Edit<T>>(); + T a_val = (a_iter.hasNext() ? a_iter.next() : null); + T b_val = (b_iter.hasNext() ? b_iter.next() : null); + a_idx = 0; + b_idx = 0; + LinkedList<ValIdx<T>> a_list = new LinkedList<ValIdx<T>>(); + LinkedList<ValIdx<T>> b_list = new LinkedList<ValIdx<T>>(); + while (a_val != null || b_val != null) { + int c = (a_val == null) ? 1 : (b_val == null) ? -1 : comp.compare(a_val, b_val); + if (c < 0) { + flushLists (a_val, a_list, b_list, ret); + a_list.addLast(new ValIdx<T>(a_val, a_idx)); + a_val = (a_iter.hasNext() ? a_iter.next() : null); + a_idx++; + } else if (c > 0) { + flushLists (b_val, a_list, b_list, ret); + b_list.addLast (new ValIdx<T>(b_val, b_idx)); + b_val = (b_iter.hasNext() ? b_iter.next() : null); + b_idx++; + } else { + flushLists (a_val, a_list, b_list, ret); + a_val = (a_iter.hasNext() ? a_iter.next() : null); + a_idx++; + b_val = (b_iter.hasNext() ? b_iter.next() : null); + b_idx++; + } + } + flushLists(a_list, b_list, ret); + return ret; + } + } + + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp an DiffEquals (equality tester) used to determine if entries from a and b are equal + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + */ + public static <T> int editDist (List<T> a, List<T> b, DiffEquals<T> comp) { + DistWork<T> distwork = new DistWork<T>(a,b,comp); + return distwork.dist(); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + * <p> + * Uses a.equals(b) to determine if entries from a and b are equal + */ + public static <T> int editDist (List<T> a, List<T> b) { + return editDist(a,b,new DiffEqualsDefault<T>()); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp a Comparator used to determine if entries from a and b are equal + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + */ + public static <T> int editDist (List<T> a, List<T> b, Comparator<T> comp) { + return editDist(a,b,new DiffEqualsFromCompare<T>(comp)); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp a Comparator used to determine if entries from a and b are equal + * @param canChange a Comparator used to determine if an entry from a can be changed to an entry from b + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + */ + public static <T> int editDist (List<T> a, List<T> b, Comparator<T> comp, Comparator<T> canChange) { + return editDist(a,b,new DiffEqualsCompareChange<T>(comp, canChange)); + } + + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp an DiffEquals (equality tester) used to determine if entries from a and b are equal + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + * <p> + * This version outputs (to System.out) a line of statistics about the objects used + */ + protected static <T> int editDistStats (List<T> a, List<T> b, DiffEquals<T> comp) { + Date start = new Date(); + DistWork<T> distwork = new DistWork<T>(a,b,comp); + int d = distwork.dist(); + Date end = new Date(); + double elapsed = (end.getTime() - start.getTime())/1000.0; + distwork.dumpStats("length " + a.size() + "/" + b.size() + " distance="+d+" elapsed="+elapsed); + return d; + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + * <p> + * Uses a.equals(b) to determine if entries from a and b are equal + * <p> + * This version outputs (to System.out) a line of statistics about the objects used + */ + protected static <T> int editDistStats (List<T> a, List<T> b) { + return editDistStats(a,b,new DiffEqualsDefault<T>()); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp a Comparator used to determine if entries from a and b are equal + * @return the edit distance between a and b (the number of add, delete, and change + * operations needed to convert a to b). + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + * <p> + * This version outputs (to System.out) a line of statistics about the objects used + */ + protected static <T> int editDistStats (List<T> a, List<T> b, Comparator<T> comp) { + return editDistStats(a,b,new DiffEqualsFromCompare<T>(comp)); + } + + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp an DiffEquals (equality tester) used to determine if entries from a and b are equal + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + */ + public static <T> List<Edit<T>> editScript (List<T> a, List<T> b, DiffEquals<T> comp) { + DistWork<T> distwork = new DistWork<T>(a,b,comp); + return distwork.script(); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + * <p> + * Uses a.equals(b) to determine if entries from a and b are equal + */ + public static <T> List<Edit<T>> editScript (List<T> a, List<T> b) { + return editScript(a,b,new DiffEqualsDefault<T>()); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp a Comparator used to determine if entries from a and b are equal + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + */ + public static <T> List<Edit<T>> editScript (List<T> a, List<T> b, Comparator<T> comp) { + return editScript(a,b,new DiffEqualsFromCompare<T>(comp)); + } + /** + * @param a input list for the comparison. The list should support efficient random access (a.get(i)) + * @param b input list for the comparison. The list should support efficient random access (b.get(i)) + * @param comp a Comparator used to determine if entries from a and b are equal + * @param canChange a Comparator used to determine if an entry from a can be changed to an entry from b + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(nD) and space O(n+D^2), where n is the length of the length of lists and + * D is the edit distance + */ + public static <T> List<Edit<T>> editScript (List<T> a, List<T> b, Comparator<T> comp, Comparator<T> canChange) { + return editScript(a,b,new DiffEqualsCompareChange<T>(comp, canChange)); + } + + /** + * @param a input list for the comparison. a cannot contain nulls + * @param b input list for the comparison. b cannot contain nulls + * @param comp a DiffCompare used to order the entries from a and b. + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(n) and space O(n), where n is the length of the length of lists + */ + public static <T> List<Edit<T>> editScriptSorted (Collection<T> a, Collection<T> b, DiffCompare<T> comp) { + DistWorkSorted<T> distwork = new DistWorkSorted<T>(a,b,comp); + return distwork.script(); + } + /** + * @param a input list for the comparison. a cannot contain nulls + * @param b input list for the comparison. b cannot contain nulls + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(n) and space O(n), where n is the length of the length of lists + * <p> + * Uses a.compareTo(b) to determine item ordering, and allows all changes + */ + public static <T extends Comparable<T>> List<Edit<T>> editScriptSorted (Collection<T> a, Collection<T> b) { + return editScriptSorted(a,b,new DiffComparable<T>()); + } + /** + * @param a input list for the comparison. a cannot contain nulls + * @param b input list for the comparison. b cannot contain nulls + * @param comp a Comparator used to order the entries from a and b. + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(n) and space O(n), where n is the length of the length of lists + */ + public static <T> List<Edit<T>> editScriptSorted (Collection<T> a, Collection<T> b, Comparator<T> comp) { + return editScriptSorted(a,b,new DiffComparator<T>(comp)); + } + /** + * @param a input list for the comparison. a cannot contain nulls + * @param b input list for the comparison. b cannot contain nulls + * @param comp a Comparator used to order the entries from a and b. + * @param canChange a Comparator used to decide if entries from a can be changed to entries from b + * @return A list of edit operations converting a to b + * <p> + * Runs in time O(n) and space O(n), where n is the length of the length of lists + */ + public static <T> List<Edit<T>> editScriptSorted (Collection<T> a, Collection<T> b, Comparator<T> comp, Comparator<T> canChange) { + return editScriptSorted(a,b,new DiffCompareChange<T>(comp, canChange)); + } + /** + * Combines pairs of edits of type {@link EditType#OnlyInA} and {@link EditType#OnlyInB} + * into edits of type {@link EditType#ReplaceAwithB}. + * <p> + * The edits will be paired in the order they occur, but it pass over intermediate edits + * of type {@link EditType#ChangeAtoB}. Thus, for example, an edit list of + * {@code OnlyInB, ChangeAtoB, OnlyIn B, OnlyInA} will be merged into + * {@code ChangeAtoB, OnlyInB, ReplaceAwithB}. + * + * @param edits the input edit script + * @return the merged edit script + */ + public static <T> List<Edit<T>> mergeReplaces (Collection<Edit<T>> edits) { + List<Edit<T>> ret = new LinkedList<Edit<T>>(); + LinkedList<Edit<T>> alist = new LinkedList<Edit<T>>(); + LinkedList<Edit<T>> blist = new LinkedList<Edit<T>>(); + int acount = 0; + int bcount = 0; + + for (Edit<T> edit : edits) { + switch (edit.type) { + case OnlyInA: acount++; break; + case OnlyInB: bcount++; break; + default: break; + } + } + + for (Edit<T> edit : edits) { + switch (edit.type) { + case OnlyInA: + if (!blist.isEmpty()) { + Edit<T> b = blist.removeFirst(); + ret.add(new Edit<T>(EditType.ReplaceAwithB, edit.a_index, b.b_index, edit.a_value, b.b_value)); + } else if (bcount > 0) { + acount--; + bcount--; + alist.add(edit); + } else { + acount--; + ret.add(edit); + } + break; + case OnlyInB: + if (!alist.isEmpty()) { + Edit<T> a = alist.removeFirst(); + ret.add(new Edit<T>(EditType.ReplaceAwithB, a.a_index, edit.b_index, a.a_value, edit.b_value)); + } else if (acount > 0) { + acount--; + bcount--; + blist.add(edit); + } else { + bcount--; + ret.add(edit); + } + break; + default: + ret.add(edit); + break; + } + } + + if (!alist.isEmpty() || !blist.isEmpty()) { + throw new RuntimeException("temporary list not empty in DiffUtil.mergeReplaces"); + } + + return ret; + } + + private static class DistWorkSimple<T> { + private final List<T> a; + private final List<T> b; + private final DiffEquals<T> comp; + private final int[] dists; + public DistWorkSimple(List<T> a, List<T> b, DiffEquals<T> comp) { + this.a = a; + this.b = b; + this.comp = comp; + dists = new int[(a.size()+1) * (b.size()+1)]; + } + public int dist() { + for (int j=0; j<=b.size(); j++) { + dists[j] = j; + } + for (int i=1; i<=a.size(); i++) { + int row = i*(b.size()+1); + int prow = (i-1)*(b.size()+1); + dists[row] = i; + for (int j=1; j<=b.size(); j++) { + if (comp.equals(a.get(i-1),b.get(j-1))) { + dists[row+j] = dists[prow+j-1]; + } else { + int d = dists[prow+j]; + if (dists[row+j-1] < d) d = dists[row+j-1]; + if (dists[prow+j-1] < d && comp.canChange(a.get(i-1), b.get(j-1))) { + d = dists[prow+j-1]; + } + dists[row+j] = d+1; + } + } + } + return dists[a.size() * (b.size()+1) + b.size()]; + } + } + protected static <T> int editDistSimple (List<T> a, List<T> b, DiffEquals<T> comp) { + DistWorkSimple<T> distwork = new DistWorkSimple<T>(a,b,comp); + return distwork.dist(); + } + protected static <T> int editDistSimple (List<T> a, List<T> b) { + return editDistSimple(a,b,new DiffEqualsDefault<T>()); + } + protected static <T> int editDistSimple (List<T> a, List<T> b, Comparator<T> comp) { + return editDistSimple(a,b,new DiffEqualsFromCompare<T>(comp)); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/DiffUtilTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/DiffUtilTest.java new file mode 100644 index 0000000..9369372 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/DiffUtilTest.java @@ -0,0 +1,240 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import org.openecomp.ncomp.utils.DiffUtil.Edit; +import org.openecomp.ncomp.utils.DiffUtil.EditType; + +import junit.framework.TestCase; + +public class DiffUtilTest extends TestCase { + private void stringtest (String a, String b, int expect) { + List<String> alist = Arrays.asList(a.split("")); + List<String> blist = Arrays.asList(b.split("")); + int got = DiffUtil.editDist(alist.subList(1, alist.size()), blist.subList(1,blist.size())); + assertEquals("editDist " + a + " " + b, expect, got); + } + private void stringscript (String a, String b, int expect) { + List<String> alist = Arrays.asList(a.split("")); + List<String> blist = Arrays.asList(b.split("")); + List<Edit<String>> script = DiffUtil.editScript(alist.subList(1, alist.size()), blist.subList(1,blist.size())); + assertEquals("editScript " + a + " " + b, expect, script.size()); + } + private void stringtest_nochange (String a, String b, int expect) { + List<String> alist = Arrays.asList(a.split("")); + List<String> blist = Arrays.asList(b.split("")); + int got = DiffUtil.editDist(alist.subList(1, alist.size()), blist.subList(1,blist.size()), + new DiffUtil.DiffEqualsNoChange<String>()); + assertEquals("editDist " + a + " " + b, expect, got); + } + public void test_simple() { + String a = "simpletest"; + String b = "complextest"; + stringtest (a, b, 3); + stringtest (b, a, 3); + stringtest ("simple", "dimple", 1); + stringtest ("simple", "sample", 1); + stringtest ("simple", "simply", 1); + stringscript (a, b, 3); + stringscript (b, a, 3); + } + public void test_nochange() { + String a = "simpletest"; + String b = "complextest"; + stringtest_nochange (a, b, 5); + stringtest_nochange (b, a, 5); + stringtest_nochange ("simple", "dimple", 2); + stringtest_nochange ("simple", "sample", 2); + stringtest_nochange ("simple", "simply", 2); + } + private int gentest (long seed, List<Integer> alist, List<Integer> blist, int n, double pa, + double pb, double pc) { + alist.clear(); + blist.clear(); + SecureRandom r = new SecureRandom(); + r.setSeed(seed); + int dist = 0; + for (int i=0; i<n; i++) { + double p = r.nextDouble(); + if (p < pa) { + blist.add(r.nextInt()); + dist++; + } else if (p < pa+pb) { + alist.add(r.nextInt()); + dist++; + } else if (p < pa+pb+pc) { + alist.add(r.nextInt()); + blist.add(r.nextInt()); + dist++; + } else { + int d = r.nextInt(); + alist.add(d); + blist.add(d); + } + } + return dist; + } + private List<Edit<Integer>> gentestscript (long seed, List<Integer> alist, List<Integer> blist, int n, double pa, + double pb, double pc) { + alist.clear(); + blist.clear(); + List<Edit<Integer>> ret = new ArrayList<Edit<Integer>>(); + SecureRandom r = new SecureRandom(); + r.setSeed(seed); + for (int i=0; i<n; i++) { + double p = r.nextDouble(); + if (p < pa) { + blist.add(r.nextInt()); + ret.add(new Edit<Integer>(EditType.OnlyInB, -1, blist.size()-1, null, blist.get(blist.size()-1))); + } else if (p < pa+pb) { + alist.add(r.nextInt()); + ret.add(new Edit<Integer>(EditType.OnlyInA, alist.size()-1, -1, alist.get(alist.size()-1), null)); + } else if (p < pa+pb+pc) { + alist.add(r.nextInt()); + blist.add(r.nextInt()); + ret.add(new Edit<Integer>(EditType.ChangeAtoB, alist.size()-1, blist.size()-1, alist.get(alist.size()-1), blist.get(blist.size()-1))); + } else { + int d = r.nextInt(); + alist.add(d); + blist.add(d); + } + } + return ret; + } + public void test_stats() { + List<Integer> alist = new ArrayList<Integer>(); + List<Integer> blist = new ArrayList<Integer>(); + List<Edit<Integer>> script1; + List<Edit<Integer>> script2; + int d1; + int d2; + script1 = gentestscript(100, alist, blist, 100, 0.01, 0.01, 0.01); + script2 = DiffUtil.editScript(alist, blist); + assertTrue("editScript random 100 0.01", script1.equals(script2)); + d1 = script1.size(); + d2 = DiffUtil.editDistStats(alist, blist); + assertEquals("editDist random 100 0.01", d1,d2); + d2 = DiffUtil.editDistSimple(alist, blist); + assertEquals("editDistSimple random 100 0.01", d1,d2); + script1 = gentestscript(110, alist, blist, 1000, 0.01, 0.01, 0.01); + script2 = DiffUtil.editScript(alist, blist); + assertTrue("editScript random 1000 0.01", script1.equals(script2)); + d1 = script1.size(); + d2 = DiffUtil.editDistStats(alist, blist); + assertEquals("editDist random 1000 0.01", d1,d2); + d2 = DiffUtil.editDistSimple(alist, blist); + assertEquals("editDistSimple random 1000 0.01", d1,d2); + d1 = gentest(120, alist, blist, 1000, 0.1, 0.1, 0.1); + d2 = DiffUtil.editDistStats(alist, blist); + assertEquals("editDist random 1000 0.1", 265,d2); + d2 = DiffUtil.editDistSimple(alist, blist); + assertEquals("editDistSimple random 1000 0.1", 265,d2); + d1 = gentest(130, alist, blist, 10000, 0.01, 0.01, 0.01); + d2 = DiffUtil.editDistStats(alist, blist); + assertEquals("editDist random 10000 0.01", 296, d2); +// d2 = DiffUtil.editDistSimple(alist, blist); +// assertEquals("editDistSimple random 10000 0.01", 296, d2); + script1 = gentestscript(140, alist, blist, 10000, 0.001, 0.001, 0.001); + script2 = DiffUtil.editScript(alist, blist); + assertTrue("editScript random 10000 0.001", script1.equals(script2)); + d1 = script1.size(); + d2 = DiffUtil.editDistStats(alist, blist); + assertEquals("editDist random 10000 0.001", d1, d2); + script1 = gentestscript(150, alist, blist, 100000, 0.001, 0.001, 0.001); + script2 = DiffUtil.editScript(alist, blist); + assertTrue("editScript random 100000 0.001", script1.equals(script2)); + d1 = script1.size(); + d2 = DiffUtil.editDistStats(alist, blist); + assertEquals("editDist random 100000 0.001", d1, d2); + } + public void test_fenceposts() { + String a = "simpletest"; + String b = "asimpletest"; + String c = "simpletestx"; + stringtest (a, b, 1); + stringtest (a, c, 1); + stringtest (b, c, 2); + stringtest (b, a, 1); + stringtest (c, a, 1); + stringtest (c, b, 2); + String x = "aaaaaaaaaa"; + String y = "abababababababababab"; + String z = "babababababababababa"; + stringtest (x, y, 10); + stringtest (y, x, 10); + stringtest (x, z, 10); + stringtest (z, x, 10); + stringtest (y, z, 2); + stringtest (z, y, 2); + stringtest ("", "hello", 5); + stringtest ("hello", "", 5); + stringtest ("", "", 0); + stringtest ("hello", "hello", 0); + } + private static class CompareFirst implements Comparator<String> { + public int compare(String a, String b) { + return a.substring(0,1).compareTo(b.substring(0,1)); + } + } + private static class CompareString implements Comparator<String> { + public int compare(String a, String b) { + return a.compareTo(b); + } + } + + public void test_sorted() { + CompareFirst cf = new CompareFirst(); + CompareString cs = new CompareString(); + List<String> a = new ArrayList<String>(); + List<String> b = new ArrayList<String>(); + a.add("aaa"); + a.add("abc"); + a.add("cba"); + List<Edit<String>> script; + script = DiffUtil.editScriptSorted(a, b); + assertEquals("sorted test 1", 3, script.size()); + script = DiffUtil.editScriptSorted(a, b, cs, cf); + assertEquals("sorted test 2", 3, script.size()); + b.add("baa"); + script = DiffUtil.editScriptSorted(a, b); + assertEquals("sorted test 3", 3, script.size()); + script = DiffUtil.mergeReplaces(script); + assertEquals("merged test 3", 3, script.size()); + script = DiffUtil.editScriptSorted(a, b, cs, cf); + assertEquals("sorted test 4", 4, script.size()); + script = DiffUtil.mergeReplaces(script); + assertEquals("merged test 4", 3, script.size()); + b.add("caa"); + b.add("cba"); + a.add("cca"); + script = DiffUtil.editScriptSorted(a, b, cs, cf); + assertEquals("sorted test 5", 4, script.size()); + script = DiffUtil.mergeReplaces(script); + assertEquals("merged test 5", 3, script.size()); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/FindFiles.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/FindFiles.java new file mode 100644 index 0000000..ee9cf96 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/FindFiles.java @@ -0,0 +1,728 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +//import org.apache.hadoop.conf.Configuration; +//import org.apache.hadoop.fs.FileStatus; +//import org.apache.hadoop.fs.FileSystem; +//import org.apache.hadoop.fs.Path; +import org.apache.log4j.Logger; + +import org.openecomp.ncomp.webservice.utils.DateUtils; + +public class FindFiles { + public static final Logger logger = Logger.getLogger("org.openecomp.ncomp.utils.io.findfiles"); + + private int numDays = 10; + private int numDaysWarning = 7; + private String email = null; + private int minSize = 0; + private int intervalSeconds = 24 * 3600; + private boolean gmt = true; + private boolean allowMultipleMatches = false; + // private Date date; + private String format; + private List<String> parameters; + + private String hdfsUri; + +// private FileSystem hdfsFs; + + /** + * @param format + */ + public FindFiles(String format) { + this.format = format; + this.parameters = new ArrayList<String>(); + } + + public FindFiles(String format, List<String> parameters) { + this.format = format; + this.parameters = parameters; + } + + public FindFiles(String format, String[] p) { + this.format = format; + parameters = new ArrayList<String>(); + for (String pp : p) { + parameters.add(pp); + } + } + + public int getNumDays() { + return numDays; + } + + public void setNumDays(int numDays) { + this.numDays = numDays; + } + + public int getNumDaysWarning() { + return numDaysWarning; + } + + public void setNumDaysWarning(int numDaysWarning) { + this.numDaysWarning = numDaysWarning; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public int getMinSize() { + return minSize; + } + + public void setMinSize(int minSize) { + this.minSize = minSize; + } + + public int getIntervalSeconds() { + return intervalSeconds; + } + + public void setIntervalSeconds(int intervalSeconds) { + throw new RuntimeException("Currently only daily granularity is suppported"); + // this.intervalSeconds = intervalSeconds; + } + + public boolean isGmt() { + return gmt; + } + + public void setGmt(boolean gmt) { + this.gmt = gmt; + } + + public boolean isAllowMultipleMatches() { + return allowMultipleMatches; + } + + public void setAllowMultipleMatches(boolean allowMultipleMatches) { + this.allowMultipleMatches = allowMultipleMatches; + } + + public String findFile() { + Calendar end = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + Calendar start = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + start.add(Calendar.DAY_OF_MONTH, -numDays); + List<ParameterizedFile> pfiles = findFiles(start.getTime(), end.getTime()); + int i = pfiles.size(); + if (i == 0) + return null; + return pfiles.get(i - 1).getFile(); + } + + public class ParameterizedFile implements Comparable<ParameterizedFile> { + public ParameterizedFile(ParameterizedFile current) { + file = new StringBuffer(current.file); + date = current.getDate(); + values = current.values.clone(); + } + + public ParameterizedFile(Date date) { + this.date = date; + ; + } + + public String getFile() { + return file.toString(); + } + + public Date getDate() { + return date; + } + + public String[] getValues() { + return values; + } + + StringBuffer file = new StringBuffer(); + Date date;; + String[] values = new String[parameters.size()]; + + @Override + public String toString() { + return "ParametizedFile [date=" + date + ", file=" + file + ", values=" + Arrays.toString(values) + "]"; + } + + public void setDate(Date time) { + date = time; + } + + @Override + public int compareTo(ParameterizedFile o) { + return date.compareTo(o.getDate()); + } + + } + + public List<ParameterizedFile> findFiles() { + String[] l = {}; + return findFiles(l); + } + + public List<ParameterizedFile> findFiles(String[] values) { + Date date = new Date(); + List<ParameterizedFile> res = new ArrayList<ParameterizedFile>(); + // hack to handle dos filesystems, where format may be "c:/..." + MyFile root = new MyFile(new File(format.split("/")[0] + "/")); + List<PathSegment> segs = new ArrayList<PathSegment>(); + for (String s : format.split("/")) { + segs.add(new PathSegment(s, date, values)); + } + ParameterizedFile f = new ParameterizedFile(date); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTime(date); + findFilesInternal(date, root, segs, 1, values, f, cal, res); + return res; + } + + public List<ParameterizedFile> findFiles(Date date) { + String[] l = {}; + Date start = new Date((date.getTime() / 1000 / intervalSeconds) * intervalSeconds * 1000); + Date end = new Date((date.getTime() / 1000 / intervalSeconds + 1) * intervalSeconds * 1000); + return findFiles(start, end, l); + } + + public List<ParameterizedFile> findFiles(Date start, Date end) { + String[] l = {}; + return findFiles(start, end, l); + } + + public List<ParameterizedFile> findFiles(Date start, Date end, String[] values) { + List<ParameterizedFile> res = new ArrayList<ParameterizedFile>(); + // hack to handle dos filesystems, where format may be "c:/..." + MyFile root = new MyFile(new File(format.split("/")[0] + "/")); + Date date = new Date(start.getTime() / intervalSeconds / 1000 * 1000 * intervalSeconds); + while (date.before(end)) { + List<PathSegment> segs = new ArrayList<PathSegment>(); + for (String s : format.split("/")) { + segs.add(new PathSegment(s, date, values)); + } + ParameterizedFile f = new ParameterizedFile(date); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTime(date); + findFilesInternal(date, root, segs, 1, values, f, cal, res); + date = new Date(date.getTime() + 1000 * getIntervalSeconds()); + } + List<ParameterizedFile> res2 = new ArrayList<ParameterizedFile>(); + for (ParameterizedFile f : res) { + if (logger.isDebugEnabled()) + logger.debug(f + " " + start + " " + end + " " + start.after(f.getDate()) + " " + + f.getDate().after(end)); + if (start.after(f.getDate()) || (!f.getDate().before(end))) + continue; + res2.add(f); + } + return res2; + } + + public ParameterizedFile findLastFile() { + String[] l = {}; + return findLastFile(l); + } + + public ParameterizedFile findLastFile(Date after) { + String[] l = {}; + return findLastFile(l, after); + } + + public ParameterizedFile findLastFile(String[] values) { + Date after = DateUtils.dateFromString("-30day"); + return findLastFile(values, after); + } + + /** + * @param values + * @param after + * Only consider files after this date. + * @return + */ + public ParameterizedFile findLastFile(String[] values, Date after) { + // hack to handle DOS file systems, where format may be "c:/..." + File root = new File(format.split("/")[0] + "/"); + List<PathSegment> segs = new ArrayList<PathSegment>(); + for (String s : format.split("/")) { + segs.add(new PathSegment(s, values)); + } + ParameterizedFile f = new ParameterizedFile(new Date()); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + after.setTime(after.getTime() / 24 / 3600 / 1000 * 24 * 3600 * 1000); + cal.setTimeInMillis(after.getTime()); + return findLastFileInternal(root, segs, 1, values, f, cal, after); + } + + public class PathSegment { + String str; + Pattern pattern; + List<Character> parameters = new ArrayList<Character>(); + + private String encode(String s) { + return s.replace("\\*", ".*").replace("\\?", "."); + } + + public PathSegment(String str1, Date date, String[] values) { + str = str1; + if (str.equals("**")) { + if (logger.isDebugEnabled()) + logger.debug("str=" + str + " buf=^.*$"); + pattern = Pattern.compile("^.*$"); + return; + } + StringBuffer buf = new StringBuffer("^"); + int index2 = 0; + for (int index = str.indexOf('%', index2); index != -1; index = str.indexOf('%', index2)) { + Character c = str.charAt(index + 1); + parameters.add(c); + buf.append(encode(str.substring(index2, index))); + if ('0' <= c && c <= '9') { + // parameter + int i = c - '0'; + if (i >= FindFiles.this.parameters.size()) + throw new RuntimeException("Too large index " + i + " " + FindFiles.this.parameters + " " + + values); + String s = i < values.length ? values[i] : null; + if (s == null) + s = ".*"; + else + s = encode(s); + buf.append("(" + s + ")"); + } else { + // Time specifier + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); + switch (c) { + case 'Y': + buf.append(String.format("%tY", date)); + break; + case 'y': + buf.append(String.format("%ty", date)); + break; + case 'm': + buf.append(String.format("%tm", date)); + break; + case 'd': + buf.append(String.format("%td", date)); + break; + case 'S': + case 'M': + case 'H': + buf.append("(\\d\\d)"); + break; + case 'k': + buf.append("(\\d\\d|\\d)"); + break; + case 'U': + buf.append("(\\d*)"); + break; + default: + throw new RuntimeException("Unknown pattern specifier: " + c); + } + } + index2 = index + 2; + } + buf.append(encode(str.substring(index2)) + "$"); + if (logger.isDebugEnabled()) + logger.debug("date=" + date + " str=" + str + " buf=" + buf); + pattern = Pattern.compile(buf.toString()); + } + + public PathSegment(String str1, String[] values) { + str = str1; + StringBuffer buf = new StringBuffer("^"); + int index2 = 0; + for (int index = str.indexOf('%', index2); index != -1; index = str.indexOf('%', index2)) { + Character c = str.charAt(index + 1); + parameters.add(c); + buf.append(encode(str.substring(index2, index))); + if ('0' <= c && c <= '9') { + // parameter + int i = c - '0'; + if (i >= FindFiles.this.parameters.size()) + throw new RuntimeException("Too large index " + i + " " + FindFiles.this.parameters + " " + + values); + String s = i < values.length ? values[c - '0'] : null; + if (s == null) + s = ".*"; + else + s = encode(s); + buf.append("(" + s + ")"); + } else { + // Time specifier + switch (c) { + case 'Y': + buf.append("(\\d\\d\\d\\d)"); + break; + case 'y': + case 'm': + case 'd': + case 'S': + case 'M': + case 'H': + buf.append("(\\d\\d)"); + break; + case 'k': + buf.append("(\\d\\d|\\d)"); + break; + case 'U': + buf.append("(\\d*)"); + break; + default: + throw new RuntimeException("Unknown pattern specifier: " + c); + } + } + index2 = index + 2; + } + buf.append(encode(str.substring(index2)) + "$"); + if (logger.isDebugEnabled()) + logger.debug("str=" + str + " buf=" + buf); + pattern = Pattern.compile(buf.toString()); + } + + public boolean match(String name, ParameterizedFile pfile, Calendar cal) { + Matcher m = pattern.matcher(name); + boolean b = m.find(); + int index = 1; + if (logger.isDebugEnabled()) + logger.debug("Match " + str + " name=" + name + " match=" + b); + if (!b) + return false; + for (Character c : parameters) { + if ('0' <= c && c <= '9') { + pfile.values[c - '0'] = m.group(index++); + } else { + // Time specifier + switch (c) { + case 'm': + case 'd': + case 'y': + case 'Y': + break; + case 'S': + cal.set(Calendar.SECOND, Integer.parseInt(m.group(index++))); + break; + case 'M': + cal.set(Calendar.MINUTE, Integer.parseInt(m.group(index++))); + break; + case 'k': + case 'H': + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(index++))); + break; + case 'U': + cal.setTime(DateUtils.unix2date(m.group(index++))); + break; + default: + throw new RuntimeException("Unknown pattern specifier: " + c); + } + } + } + return true; + } + + public boolean matchFull(String name, ParameterizedFile pfile, Calendar cal) { + Matcher m = pattern.matcher(name); + boolean b = m.find(); + int index = 1; + if (logger.isDebugEnabled()) + logger.debug("Match " + str + " name=" + name + " match=" + b); + if (!b) + return false; + for (Character c : parameters) { + if ('0' <= c && c <= '9') { + pfile.values[c - '0'] = m.group(index++); + } else { + // Time specifier + switch (c) { + case 'm': + // month is numbered from zero + cal.set(Calendar.MONTH, Integer.parseInt(m.group(index++)) - 1); + break; + case 'd': + cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(index++))); + break; + case 'y': + cal.set(Calendar.YEAR, 2000 + Integer.parseInt(m.group(index++))); + break; + case 'Y': + cal.set(Calendar.YEAR, Integer.parseInt(m.group(index++))); + break; + case 'S': + cal.set(Calendar.SECOND, Integer.parseInt(m.group(index++))); + break; + case 'M': + cal.set(Calendar.MINUTE, Integer.parseInt(m.group(index++))); + break; + case 'k': + case 'H': + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(index++))); + break; + case 'U': + cal.setTime(DateUtils.unix2date(m.group(index++))); + break; + default: + throw new RuntimeException("Unknown pattern specifier: " + c); + } + } + } + return true; + } + + public boolean isRecursive() { + return str.equals("**"); + } + } + + private void findFilesInternal(Date date, MyFile dir, List<PathSegment> segs, int index, String[] values, + ParameterizedFile current, Calendar cal, List<ParameterizedFile> res) { + PathSegment seg = segs.get(index); + List<MyFile> files = dir.listFiles(); + if (files == null) { + if (logger.isDebugEnabled()) + logger.debug("Unable to read directory " + dir.getAbsolutePath()); + return; + } + if (seg.isRecursive()) { + findFilesInternal(date, dir, segs, index + 1, values, current, cal, res); + } + for (MyFile file : files) { + if (!seg.match(file.getName(), current, cal)) { + if (logger.isDebugEnabled()) + logger.debug("Ignore " + file.getAbsolutePath()); + continue; + } + ParameterizedFile f = new ParameterizedFile(current); + f.file.append("/" + file.getName()); + if (index + 1 == segs.size()) { + f.setDate(cal.getTime()); + res.add(f); + } else { + if (file.isDirectory()) { + findFilesInternal(date, file, segs, index + 1, values, f, cal, res); + if (seg.isRecursive()) { + findFilesInternal(date, file, segs, index, values, f, cal, res); + } + } else if (logger.isDebugEnabled()) + logger.debug("Ignore2 " + file.getAbsolutePath()); + } + } + } + + private class MyFile { +// public MyFile(FileStatus fileStatus) { +// h = fileStatus; +// } + public boolean isDirectory() { +// if (h != null) + return f.isDirectory(); +// return h.isDir(); + } + public List<MyFile> listFiles() { + List<MyFile> res = new ArrayList<MyFile>(); + if (hdfsUri != null) { +// try { +// FileStatus[] status = hdfsFs.listStatus(new Path(getAbsolutePath())); +// for (int i = 0; i < status.length; i++) { +// res.add(new MyFile(status[i])); +// } +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + } + else { + File[] files = f.listFiles(); + for (int i = 0; i < files.length; i++) { + res.add(new MyFile(files[i])); + } + } + return res; + } + public String getAbsolutePath() { +// if (f != null) + return f.getAbsolutePath(); +// return h.getPath().toString(); + } + public String getName() { +// if (f != null) + return f.getName(); +// return h.getPath().getName(); + } + public MyFile(File file) { + f = file; + } + File f; +// FileStatus h; + } + + private ParameterizedFile findLastFileInternal(File dir, List<PathSegment> segs, int index, String[] values, + ParameterizedFile current, Calendar cal, Date after) { + final class FileDate implements Comparable<FileDate> { + public final File file; + public final ParameterizedFile pf; + public final Calendar cal; + + FileDate(File file, ParameterizedFile pf, Calendar cal) { + this.file = file; + this.pf = pf; + this.cal = cal; + } + + @Override + public int compareTo(FileDate x) { + return -cal.compareTo(x.cal); + } + } + PathSegment seg = segs.get(index); + File[] files = dir.listFiles(); + if (files == null) { + if (logger.isDebugEnabled()) + logger.debug("Unable to read directory " + dir.getAbsolutePath()); + return null; + } + List<FileDate> children = new ArrayList<FileDate>(files.length); + for (File file : files) { + Calendar cal2 = (Calendar) cal.clone(); + if (!seg.matchFull(file.getName(), current, cal2)) { + if (logger.isDebugEnabled()) + logger.debug("Ignore " + file.getAbsolutePath()); + continue; + } + ParameterizedFile f = new ParameterizedFile(current); + f.file.append("/" + file.getName()); + if (index + 1 == segs.size() || file.isDirectory()) { + children.add(new FileDate(file, f, cal2)); + } else { + if (logger.isDebugEnabled()) + logger.debug("Ignore2 " + file.getAbsolutePath()); + } + } + java.util.Collections.sort(children); + for (FileDate fd : children) { + if (after.after(fd.cal.getTime())) + continue; + if (index + 1 == segs.size()) { + fd.pf.setDate(fd.cal.getTime()); + return fd.pf; + } else if (fd.file.isDirectory()) { + if (logger.isDebugEnabled()) + logger.debug("Considering directory" + fd.file.getAbsolutePath()); + ParameterizedFile f = findLastFileInternal(fd.file, segs, index + 1, values, fd.pf, fd.cal, after); + if (f != null) { + return f; + } + } else { + throw new RuntimeException("ignore2 vanished"); + } + } + return null; + } + + public String getFormat() { + return format; + } + + public static String convertPattern(String s) { + StringBuffer buf = new StringBuffer(); + boolean literal = false; + for (String p : s.split("'")) { + if (literal) { + buf.append(p); + } else { + buf.append(p.replace("yyyy", "%Y").replace("yy", "%y").replace("MM", "%m").replace("dd", "%d") + .replace("HH", "%H").replace("mm", "%M").replace("ss", "%S")); + } + literal = !literal; + } + return buf.toString(); + } + + public ParameterizedFile fileMatch(String file) { + List<PathSegment> segs = new ArrayList<PathSegment>(); + for (String s : format.split("/")) { + String[] l = {}; + segs.add(new PathSegment(s, l)); + } + ParameterizedFile f = new ParameterizedFile(new Date()); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTimeInMillis(0); + ParameterizedFile f1 = findMatch(file.split("/"), segs, 0, f, cal); + if (f1 != null) { + f1.setDate(cal.getTime()); + f1.file = new StringBuffer(file); + } + return f1; + } + + private ParameterizedFile findMatch(String[] parts, List<PathSegment> segs, int i, ParameterizedFile f, Calendar cal) { + if (i == parts.length && i == segs.size()) { + return f; + } + if (i >= parts.length || i >= segs.size()) + return null; + if (findMatch(parts, segs, i + 1, f, cal) == null) + return null; + PathSegment seg = segs.get(i); + String s = parts[i]; + return seg.matchFull(s, f, cal) ? f : null; + } + + public String toString(Date time, List<String> l) { + String s = format; + int index = 0; + for (String v : l) { + s = s.replace("%" + index, v); + index++; + } + return DateUtils.toString(s,time); + } + + public void setHdfs(String URI) { +// this.hdfsUri = URI; +// try { +// hdfsFs = FileSystem.get(new java.net.URI(URI),new Configuration()); +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } catch (URISyntaxException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/JvmUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/JvmUtils.java new file mode 100644 index 0000000..22a7e06 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/JvmUtils.java @@ -0,0 +1,44 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.lang.management.ManagementFactory; + +public class JvmUtils { + static long getProcessId() { + long fallback = -1; + final String jvmName = ManagementFactory.getRuntimeMXBean().getName(); + final int index = jvmName.indexOf('@'); + + if (index < 1) { + // part before '@' empty (index = 0) / '@' not found (index = -1) + return fallback; + } + + try { + return Long.parseLong(jvmName.substring(0, index)); + } catch (NumberFormatException e) { + // ignore + } + return fallback; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/MonitorUtil.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/MonitorUtil.java new file mode 100644 index 0000000..5926589 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/MonitorUtil.java @@ -0,0 +1,50 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; + +public class MonitorUtil { + + /** Get CPU time in nanoseconds. */ + static public long getCpuTime( ) { + ThreadMXBean bean = ManagementFactory.getThreadMXBean( ); + return bean.isCurrentThreadCpuTimeSupported( ) ? + bean.getCurrentThreadCpuTime( ) : 0L; + } + + /** Get user time in nanoseconds. */ + static public long getUserTime( ) { + ThreadMXBean bean = ManagementFactory.getThreadMXBean( ); + return bean.isCurrentThreadCpuTimeSupported( ) ? + bean.getCurrentThreadUserTime( ) : 0L; + } + + /** Get system time in nanoseconds. */ + static public long getSystemTime( ) { + ThreadMXBean bean = ManagementFactory.getThreadMXBean( ); + return bean.isCurrentThreadCpuTimeSupported( ) ? + (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L; + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/PathSegmentTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/PathSegmentTest.java new file mode 100644 index 0000000..ac74f15 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/PathSegmentTest.java @@ -0,0 +1,76 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import junit.framework.TestCase; + +import org.openecomp.ncomp.utils.FindFiles.ParameterizedFile; +import org.openecomp.ncomp.utils.FindFiles.PathSegment; + +public class PathSegmentTest extends TestCase { + private static final String[] parameters = { "p1", "p2" }; + private static final String[] values = { "ab.*", "cc" }; + + public void testPathSegment() { + DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); + df.setTimeZone(TimeZone.getTimeZone("GMT")); + Date d = null; + try { + d = df.parse("2/3/2010"); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + FindFiles f = new FindFiles("",parameters); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));; + ParameterizedFile pfile = f.new ParameterizedFile(d); + PathSegment p = f.new PathSegment("foo%1%Y%S%M%Hbar", d, values); + if (!p.match("foocc2010450212bar", pfile, cal)) + fail("should match"); + Date date = cal.getTime(); + if (!String.format("%tS",date).equals("45")) + fail("should match"); + PathSegment p2 = f.new PathSegment("foo%0%Y/%m/%d%S%M%Hbar", d, values); + if (p2.match("foocc2010/02/03460212bar", pfile, cal)) + fail("should not match"); + System.out.println(pfile); + if (!p2.match("fooabcc2010/02/03470212bar", pfile, cal)) + fail("should match"); + System.out.println(pfile); + if (!String.format("%tS",cal.getTime()).equals("47")) + fail("should match"); + System.out.println(pfile); + PathSegment p3 = f.new PathSegment("%U", d, values); + if (!p3.match("222222", pfile,cal)) + fail("should match"); + System.out.println(pfile); + if (!String.format("%tS",cal.getTime()).equals("42")) + fail("should match"); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/PropertyUtil.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/PropertyUtil.java new file mode 100644 index 0000000..56710a3 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/PropertyUtil.java @@ -0,0 +1,88 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.URL; +import java.util.Properties; + +import org.apache.log4j.Logger; + + + +public class PropertyUtil { + public static final Logger logger = Logger.getLogger(PropertyUtil.class); + + static public Properties getPropertiesFromClasspath(String propFileName) throws IOException { + Properties props = new Properties(); + if (propFileName == null) return props; + + InputStream inputStream = null; + + File f = new File(propFileName); + if (f.isAbsolute()) { + logger.info("Loading absolute " + f); + inputStream = new FileInputStream(f); + } else { + // loading xmlProfileGen.properties from the classpath + URL url = PropertyUtil.class.getClassLoader().getResource(propFileName); + if (url == null) { + throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath (null url)"); + } + logger.info("Loading " + url); + inputStream = PropertyUtil.class.getClassLoader().getResourceAsStream(propFileName); + if (inputStream == null) { + throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath"); + } + } + try { + props.load(inputStream); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } finally { + if (inputStream != null) + inputStream.close(); + } + + for (Object k : System.getProperties().keySet()) { + Object v = props.get(k); + if (v != null) { + logger.info("Overwriting property from system property: " + replaceForLogForcingProtection(k) + " = " + replaceForLogForcingProtection(v)); + } + props.put(k, System.getProperties().get(k)); + } + String hostname = InetAddress.getLocalHost().getHostName(); + props.put("user.hostname", hostname); + return props; + } + + public static String replaceForLogForcingProtection(Object v) { + return v.toString().replace("\n", "NEWLINE"); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/ShellCmd.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/ShellCmd.java new file mode 100644 index 0000000..05a16f3 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/ShellCmd.java @@ -0,0 +1,112 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.concurrent.TimeoutException; + +import org.apache.log4j.Logger; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class ShellCmd extends Thread { + public static final Logger logger = Logger.getLogger(ShellCmd.class); + private final Process process; + private Integer exitStatus; + private Thread t1; + private Thread t2; + private ByteArrayOutputStream e; + private ByteArrayOutputStream o; + + public static void main(String[] args) throws Exception { + ShellCmd s = new ShellCmd("/home/ncomp/test.sh"); + System.out.println(s.result(600000)); + System.err.println(s.error()); + } + + public ShellCmd(String cmd) throws IOException { + this.process = Runtime.getRuntime().exec(cmd); + o = new ByteArrayOutputStream(); + e = new ByteArrayOutputStream(); + t1 = FileUtils.copyStreamThread(process.getInputStream(), o); + t2 = FileUtils.copyStreamThread(process.getErrorStream(), e); + } + + public String error() { + return e.toString(); + } + + public String result(long wait) throws TimeoutException, InterruptedException { + try { + start(); + join(wait); + } catch (InterruptedException ex) { + interrupt(); + Thread.currentThread().interrupt(); + throw ex; + } finally { + if (process != null) { + try { + if (process.getOutputStream() != null) + process.getOutputStream().close(); + } catch (IOException e1) { + } + try { + if (process.getErrorStream() != null) + process.getErrorStream().close(); + } catch (IOException e1) { + } + try { + if (process.getInputStream() != null) + process.getInputStream().close(); + } catch (IOException e1) { + } + process.destroy(); + } + } + + if (exitStatus == null) { + t1.interrupt(); + t2.interrupt(); + System.out.println(o.toString()); + System.err.println(e.toString()); + throw new TimeoutException(); + } + if (exitStatus != 0) { + logger.warn("return error: exit status = " + exitStatus); + throw new RuntimeException("Non-Zero return status:" + exitStatus); + } + return o.toString(); + } + + public void run() { + try { + exitStatus = process.waitFor(); + t1.join(); + t2.join(); + } catch (InterruptedException ignore) { + return; + } + } +} + diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SimpleImageInfo.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SimpleImageInfo.java new file mode 100644 index 0000000..5da36fc --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SimpleImageInfo.java @@ -0,0 +1,210 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +// http://blog.jaimon.co.uk/simpleimageinfo/SimpleImageInfo.java.html + +/* + * SimpleImageInfo.java + * + * @version 0.1 + * @author Jaimon Mathew <http://www.jaimon.co.uk> + * + * A Java class to determine image width, height and MIME types for a number of image file formats without loading the whole image data. + * + * Revision history + * 0.1 - 29/Jan/2011 - Initial version created + * + * ------------------------------------------------------------------------------- + + This code is licensed under the Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + * ------------------------------------------------------------------------------- + */ + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +@SuppressWarnings("all") +public class SimpleImageInfo { + private int height; + private int width; + private String mimeType; + + private SimpleImageInfo() { + + } + + public SimpleImageInfo(File file) throws IOException { + InputStream is = new FileInputStream(file); + try { + processStream(is); + } finally { + is.close(); + } + } + + public SimpleImageInfo(InputStream is) throws IOException { + processStream(is); + } + + public SimpleImageInfo(byte[] bytes) throws IOException { + InputStream is = new ByteArrayInputStream(bytes); + try { + processStream(is); + } finally { + is.close(); + } + } + + private void processStream(InputStream is) throws IOException { + int c1 = is.read(); + int c2 = is.read(); + int c3 = is.read(); + + mimeType = null; + width = height = -1; + + if (c1 == 'G' && c2 == 'I' && c3 == 'F') { // GIF + is.skip(3); + width = readInt(is,2,false); + height = readInt(is,2,false); + mimeType = "image/gif"; + } else if (c1 == 0xFF && c2 == 0xD8) { // JPG + while (c3 == 255) { + int marker = is.read(); + int len = readInt(is,2,true); + if (marker == 192 || marker == 193 || marker == 194) { + is.skip(1); + height = readInt(is,2,true); + width = readInt(is,2,true); + mimeType = "image/jpeg"; + break; + } + is.skip(len - 2); + c3 = is.read(); + } + } else if (c1 == 137 && c2 == 80 && c3 == 78) { // PNG + is.skip(15); + width = readInt(is,2,true); + is.skip(2); + height = readInt(is,2,true); + mimeType = "image/png"; + } else if (c1 == 66 && c2 == 77) { // BMP + is.skip(15); + width = readInt(is,2,false); + is.skip(2); + height = readInt(is,2,false); + mimeType = "image/bmp"; + } else { + int c4 = is.read(); + if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) + || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { //TIFF + boolean bigEndian = c1 == 'M'; + int ifd = 0; + int entries; + ifd = readInt(is,4,bigEndian); + is.skip(ifd - 8); + entries = readInt(is,2,bigEndian); + for (int i = 1; i <= entries; i++) { + int tag = readInt(is,2,bigEndian); + int fieldType = readInt(is,2,bigEndian); + long count = readInt(is,4,bigEndian); + int valOffset; + if ((fieldType == 3 || fieldType == 8)) { + valOffset = readInt(is,2,bigEndian); + is.skip(2); + } else { + valOffset = readInt(is,4,bigEndian); + } + if (tag == 256) { + width = valOffset; + } else if (tag == 257) { + height = valOffset; + } + if (width != -1 && height != -1) { + mimeType = "image/tiff"; + break; + } + } + } + } + if (mimeType == null) { + throw new IOException("Unsupported image type"); + } + } + + private int readInt(InputStream is, int noOfBytes, boolean bigEndian) throws IOException { + int ret = 0; + int sv = bigEndian ? ((noOfBytes - 1) * 8) : 0; + int cnt = bigEndian ? -8 : 8; + for(int i=0;i<noOfBytes;i++) { + ret |= is.read() << sv; + sv += cnt; + } + return ret; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public String getMimeType() { + return mimeType; + } + + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + @Override + public String toString() { + return "MIME Type : " + mimeType + "\t Width : " + width + "\t Height : " + height; + } +} + diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SortUtil.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SortUtil.java new file mode 100644 index 0000000..4aeb176 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SortUtil.java @@ -0,0 +1,137 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +import org.openecomp.ncomp.utils.maps.HashMapList; + +public class SortUtil { + + public static + <K extends Comparable<? super K>,V> LinkedHashMap<K, V> sortMapByKey(HashMap<K,V> m) { + LinkedHashMap<K, V> res = new LinkedHashMap<K, V>(); + for (K k : SortUtil.sort(m.keySet())) { + res.put(k,m.get(k)); + } + return res; + } + public static + <K,V extends Comparable<? super V>> LinkedHashMap<K, V> sortMapByValue(HashMap<K,V> m) { + LinkedHashMap<K, V> res = new LinkedHashMap<K, V>(); + HashMapList<V,K> m1 = new HashMapList<V, K>(); + for (K k : m.keySet()) { + m1.insert(m.get(k), k); + } + for (V v : SortUtil.sort(m1.keySet())) { + for (K k: m1.get(v)) { + res.put(k,v); + } + } + return res; + } + + public static + <T extends Comparable<? super T>> List<T> sort(Collection<T> c) { + List<T> list = new ArrayList<T>(c); + java.util.Collections.sort(list); + return list; + } + + public static + <T> List<T> sort(Collection<T> c, Comparator<? super T> comp) { + List<T> list = new ArrayList<T>(c); + java.util.Collections.sort(list,comp); + return list; + } + + public static + <T extends Comparable<? super T>> + int compareList (Collection<T> a, Collection<T> b) { + Iterator<T> ai = a.iterator(); + Iterator<T> bi = b.iterator(); + while (ai.hasNext() && bi.hasNext()) { + int ret = ai.next().compareTo(bi.next()); + if (ret != 0) return ret; + } + if (bi.hasNext()) return 1; + if (ai.hasNext()) return -1; + return 0; + } + + public static <T> int compareList (Collection<T> a, Collection<T> b, Comparator<? super T> comp) { + Iterator<T> ai = a.iterator(); + Iterator<T> bi = b.iterator(); + while (ai.hasNext() && bi.hasNext()) { + int ret = comp.compare(ai.next(), bi.next()); + if (ret != 0) return ret; + } + if (bi.hasNext()) return 1; + if (ai.hasNext()) return -1; + return 0; + } + + public static + <T extends Comparable<? super T>> + int compareNull (T a, T b) { + if (a == null && b == null) return 0; + if (a == null) return 1; + if (b == null) return -1; + return a.compareTo(b); + } + + public static <T> int compareNull (T a, T b, Comparator<? super T> comp) { + if (a == null && b == null) return 0; + if (a == null) return 1; + if (b == null) return -1; + return comp.compare(a,b); + } + + public static int compareInt (int a, int b) { + if (a < b) return -1; + else if (a > b) return 1; + else return 0; + } + public static int compareFloat (float a, float b) { + if (a < b) return -1; + else if (a > b) return 1; + else return 0; + } + public static int compareDouble (double a, double b) { + if (a < b) return -1; + else if (a > b) return 1; + else return 0; + } + public static int compareBoolean (boolean a, boolean b) { + if (a && !b) return 1; + else if (!a && b) return -1; + else return 0; + } + + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/Stream2Logger.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/Stream2Logger.java new file mode 100644 index 0000000..fedd50b --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/Stream2Logger.java @@ -0,0 +1,61 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.apache.log4j.Logger; + +public class Stream2Logger { + + private class Stream2LoggerThread implements Runnable { + + @Override + public void run() { + while (true) { + try { + String line = in.readLine(); + logger.error(line); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + } + + private Logger logger; + private BufferedReader in; + private Stream2LoggerThread t; + + public Stream2Logger(InputStream in, Logger logger) { + this.logger = logger; + this.in = new BufferedReader(new InputStreamReader(in)); + t = new Stream2LoggerThread(); + t.run(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringMatcher.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringMatcher.java new file mode 100644 index 0000000..4e3a8ce --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringMatcher.java @@ -0,0 +1,178 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; + +import org.openecomp.ncomp.webservice.utils.DateUtils; + +public class StringMatcher { + public static final Logger logger = Logger.getLogger(StringMatcher.class); + private Pattern pattern; + private List<String> parameterNames = new ArrayList<String>(); + private HashMap<Integer, String> i2p = new HashMap<Integer,String>(); + private HashMap<Integer, String> i2n = new HashMap<Integer,String>(); + private List<Character> parameters = new ArrayList<Character>(); + private String str; + private String patternOrig; + + public StringMatcher(String pattern) { + patternOrig = pattern; + Pattern p = Pattern.compile("\\$\\{(.*?)}"); + Matcher m = p.matcher(pattern); + StringBuffer buf = new StringBuffer(); + int i = 0; + while (m.find()) { + String k = m.group(1); + int j = k.indexOf(":"); + if (j==-1) { + i2p.put(i,".*"); + } + else { + String kk = k.substring(0, j); + i2p.put(i,k.substring(j+1)); + k=kk; + } + if(parameterNames.contains(k)) + throw new RuntimeException("Pattern contain the same name multiple times:" + k); + parameterNames.add(k); + i2n.put(i,k); + m.appendReplacement(buf,"%"+i++); + } + m.appendTail(buf); + str = buf.toString(); + buf = new StringBuffer("^"); + int index2 = 0; + for (int index = str.indexOf('%', index2); index != -1; index = str.indexOf('%', index2)) { + Character c = str.charAt(index + 1); + parameters.add(c); + buf.append(str.substring(index2, index)); + if ('0' <= c && c <= '9') { + // parameter + int j = c - '0'; + buf.append("(" + i2p.get(j) + ")"); + } else { + // Time specifier + switch (c) { + case 'Y': + buf.append("(\\d\\d\\d\\d)"); + break; + case 'L': + buf.append("(\\d\\d\\d)"); + break; + case 'y': + case 'm': + case 'd': + case 'S': + case 'M': + case 'H': + buf.append("(\\d\\d)"); + break; + case 'k': + buf.append("(\\d\\d|\\d)"); + break; + case 's': + case 'U': // Deprecated. + buf.append("(\\d*)"); + break; + default: + throw new RuntimeException("Unknown pattern specifier: " + + c + " " + " str=" + str); + } + } + index2 = index + 2; + } + buf.append("$"); + if (logger.isDebugEnabled()) + logger.debug("pattern=" + patternOrig + " str=" + str + " buf=" + buf); + this.pattern = Pattern.compile(buf.toString()); + } + + + public boolean match(String name, HashMap<String, String> h, Date date) { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTimeInMillis(0); + Matcher m = pattern.matcher(name); + boolean b = m.find(); + int index = 1; + if (logger.isDebugEnabled()) + logger.debug("Match " + str + " name=" + name + " match=" + b); + if (!b) + return false; + for (Character c : parameters) { + if ('0' <= c && c <= '9') { + h.put(i2n.get(c - '0'),m.group(index++)); + } else { + // Time specifier + switch (c) { + case 'm': + // month is numbered from zero + cal.set(Calendar.MONTH, + Integer.parseInt(m.group(index++)) - 1); + break; + case 'd': + cal.set(Calendar.DAY_OF_MONTH, + Integer.parseInt(m.group(index++))); + break; + case 'y': + cal.set(Calendar.YEAR, + 2000 + Integer.parseInt(m.group(index++))); + break; + case 'Y': + cal.set(Calendar.YEAR, Integer.parseInt(m.group(index++))); + break; + case 'S': + cal.set(Calendar.SECOND, Integer.parseInt(m.group(index++))); + break; + case 'M': + cal.set(Calendar.MINUTE, Integer.parseInt(m.group(index++))); + break; + case 'L': + cal.set(Calendar.MILLISECOND, Integer.parseInt(m.group(index++))); + break; + case 'k': + case 'H': + cal.set(Calendar.HOUR_OF_DAY,Integer.parseInt(m.group(index++))); + break; + case 's': + case 'U': + cal.setTime(DateUtils.unix2date(m.group(index++))); + break; + default: + throw new RuntimeException("Unknown pattern specifier: " + + c); + } + } + } + date.setTime(cal.getTimeInMillis()); + return true; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringMatcherTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringMatcherTest.java new file mode 100644 index 0000000..02e385d --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringMatcherTest.java @@ -0,0 +1,55 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.util.Date; +import java.util.HashMap; +import java.util.TimeZone; + +import org.openecomp.ncomp.webservice.utils.DateUtils; + +import junit.framework.TestCase; + + + +public class StringMatcherTest extends TestCase { + public void test_match() { + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); + String x = "2014-01-04 20:01:51,987 WARN [qtp5338285-5879] org.openecomp.ncomp.bsa.controller.servers.BsaController"; + String p = "%Y-%m-%d %H:%M:%S,${millisecond:...} +${sev} \\[.*\\] ${message}"; + StringMatcher m = new StringMatcher(p); + HashMap<String,String> h = new HashMap<String, String>(); + Date date = new Date(); + assertTrue(m.match(x, h, date)); + assertEquals("2014-01-04 20:01:51",DateUtils.toString("%Y-%m-%d %H:%M:%S",date)); + assertEquals("WARN",h.get("sev")); + assertEquals("987",h.get("millisecond")); + assertEquals("org.openecomp.ncomp.bsa.controller.servers.BsaController",h.get("message")); + String p2 = "%Y-%m-%d %H:%M:%S,%L +${sev} \\[.*\\] ${message}"; + m = new StringMatcher(p2); + h = new HashMap<String, String>(); + assertTrue(m.match(x, h, date)); + assertEquals("2014-01-04 20:01:51 987",DateUtils.toString("%Y-%m-%d %H:%M:%S %L",date)); + assertEquals("WARN",h.get("sev")); + assertEquals("org.openecomp.ncomp.bsa.controller.servers.BsaController",h.get("message")); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringUtil.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringUtil.java new file mode 100644 index 0000000..cd73d53 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringUtil.java @@ -0,0 +1,197 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Properties; +import java.util.Scanner; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; +import org.json.JSONObject; + +import org.openecomp.ncomp.webservice.utils.JsonUtils; + +public class StringUtil { + public static final Logger logger = Logger.getLogger(StringUtil.class); + + public static String join(final Collection<?> l, String delim) { + boolean first = true; + StringBuffer buf = new StringBuffer(); + for (Object o : l) { + if (!first) + buf.append(delim); + else + first = false; + buf.append(o); + } + return buf.toString(); + } + + public static String join(Object[] v, String delim) { + return join(Arrays.asList(v), delim); + } + + public static String capitalize(String s) { + if (s.length() == 0) + return s; + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + + public static double parseTime(String s) { + s = s.trim(); + Scanner scan = new Scanner(s); + double d = 0; + if (scan.findInLine("^(\\d+):(\\d+\\.\\d+)$") != null) { + MatchResult result = scan.match(); + int m = Integer.parseInt(result.group(1)); + d = Double.parseDouble(result.group(2)); + scan.close(); + return d + 60 * m; + } + if (scan.findInLine("^(\\d+):(\\d+):(\\d+\\.\\d+)$") != null) { + MatchResult result = scan.match(); + int h = Integer.parseInt(result.group(1)); + int m = Integer.parseInt(result.group(2)); + d = Double.parseDouble(result.group(3)); + scan.close(); + return d + 60 * m + 3600 * h; + } + if (scan.findInLine("^(\\d+)\\.(\\d+)$") != null) { + scan.close(); + return Double.parseDouble(scan.match().group(1)); + } + logger.error("parseTime: bad time string str=" + s); + scan.close(); + return d; + } + + public static String[] split(String s, String m) { + if (s.length() == 0) { + String v[] = {}; + return v; + } + return s.split(m); + } + + public static String httpHeaderEncode(String str) { + String s = ""; + try { + s = URLEncoder.encode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + } + return s; + } + public static String httpHeaderDecode(String str) { + String s = ""; + try { + s = URLDecoder.decode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + } + return s; + } + + public static String expandUsingProperties(String string, Properties props, String prefix) { + // replace ${FOOO} with property value. + String x = prefix.equals("$") ? "\\" : ""; + StringBuffer s; + String k = null, k1 = null; + try { + Pattern p = Pattern.compile("("+x +prefix +"\\{.*?})"); + Matcher m = p.matcher(string); + s = new StringBuffer(); + while (m.find()) { + k = m.group(1); + k1 = k.substring(2,k.length()-1); + if (props.containsKey(k1)) + m.appendReplacement(s,props.getProperty(k1)); + else + m.appendReplacement(s, x+k); + } + m.appendTail(s); + return s.toString(); + } catch (IllegalArgumentException e) { + logger.debug("expand failed: " + string + " " + e + " " + k + " " + k1 + " " + props.getProperty(k1,"NULL")); + } catch (Exception e) { + logger.warn("expand failed: " + string + " " + e); + } + return string; + } + public static String expandUsingMap(String string, HashMap<String, String> map, String prefix) { + // replace ${FOOO} with property value. + String x = prefix.equals("$") ? "\\" : ""; + Pattern p = Pattern.compile("("+x +prefix +"\\{.*?})"); + Matcher m = p.matcher(string); + StringBuffer s = new StringBuffer(); + while (m.find()) { + String k = m.group(1); + String k1 = k.substring(2,k.length()-1); + if (map.containsKey(k1)) + m.appendReplacement(s,map.get(k1)); + else + m.appendReplacement(s, x+k); + } + m.appendTail(s); + return s.toString(); + } + public static String expandUsingJson(String string, JSONObject json, String prefix) { + // replace ${FOOO} with JSON string value. + String x = prefix.equals("$") ? "\\" : ""; + Pattern p = Pattern.compile("("+x +prefix +"\\{.*?})"); + Matcher m = p.matcher(string); + StringBuffer s = new StringBuffer(); + try { + while (m.find()) { + String k = m.group(1); + String k1 = k.substring(2,k.length()-1); + Object o = JsonUtils.getValue(json, k1); + if (o instanceof String) { + String v = (String) o; + m.appendReplacement(s,v.replace("$", "\\$")); + } + else if (o instanceof Integer) + m.appendReplacement(s,Integer.toString((Integer) o)); + else if (o instanceof Long) + m.appendReplacement(s,Long.toString((Long) o)); + else if (o instanceof Double) + m.appendReplacement(s,Double.toString((Double) o)); + else if (o instanceof Boolean) + m.appendReplacement(s,Boolean.toString((Boolean) o)); + else + m.appendReplacement(s, x+k); + } + } catch (Exception e) { + logger.warn("unable to expand: " + string + " " + e); + e.printStackTrace(); + throw new RuntimeException("unable to expand: " + string + " " + json.toString(2), e); + } + m.appendTail(s); + return s.toString(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringUtilTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringUtilTest.java new file mode 100644 index 0000000..c6105b5 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/StringUtilTest.java @@ -0,0 +1,61 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +import java.util.Properties; + +import org.json.JSONObject; + +import junit.framework.TestCase; + + + +public class StringUtilTest extends TestCase { + public void test_httpHeaderEncode() { + String json= "{'id':'dr.t','r':1.2,b:false,i:23,'metadata':{'empty':'foo','i':3}}"; + String e = StringUtil.httpHeaderEncode(json); + String d = StringUtil.httpHeaderDecode(e); + assertEquals(json, d); + assertFalse(e.contains(",")); + } + public void test_expandProperties() { + Properties props = new Properties(); + props.put("fff", "FFF"); + props.put("g", "FFF"); + props.put("fff.4", "FFF"); + assertEquals("FFFxxx",StringUtil.expandUsingProperties("${fff}xxx", props,"$")); + assertEquals("FFFxxFFFx",StringUtil.expandUsingProperties("${fff.4}xx${g}x", props,"$")); + assertEquals("${ff}xxx",StringUtil.expandUsingProperties("${ff}xxx", props,"$")); + assertEquals("FFFxxx",StringUtil.expandUsingProperties("%{fff}xxx", props,"%")); + assertEquals("FFFxxFFFx",StringUtil.expandUsingProperties("%{fff.4}xx%{g}x", props,"%")); + assertEquals("%{ff}xxx",StringUtil.expandUsingProperties("%{ff}xxx", props,"%")); + } + public void test_expandUsingJson() { + JSONObject json = new JSONObject("{'id':'dr.t','r':1.2,b:false,i:23,l:1372953720000,'metadata':{'empty':'foo','i':3}}"); + assertEquals("yyydr.txxx",StringUtil.expandUsingJson("yyy${id}xxx", json,"$")); + assertEquals("yyyfooxxx",StringUtil.expandUsingJson("yyy${metadata.empty}xxx", json,"$")); + assertEquals("yyy3xxx",StringUtil.expandUsingJson("yyy${metadata.i}xxx", json,"$")); + assertEquals("yyy1.2xxx",StringUtil.expandUsingJson("yyy${r}xxx", json,"$")); + assertEquals("yyyfalsexxx",StringUtil.expandUsingJson("yyy${b}xxx", json,"$")); + assertEquals("yyy1372953720000xxx",StringUtil.expandUsingJson("yyy${l}xxx", json,"$")); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SwigUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SwigUtils.java new file mode 100644 index 0000000..657cf18 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/SwigUtils.java @@ -0,0 +1,39 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils; + +public class SwigUtils { + private static boolean libraryLoad = false; + static { + libraryLoad = false; + try { + System.loadLibrary("swig"); + libraryLoad = true; + System.out.println("SwigUtils: Using SWIG library"); + } catch (java.lang.UnsatisfiedLinkError e) { + System.out.println("SwigUtils: Unable to load swig library: " + e); + } + } + public static boolean isLibraryLoaded() { + return libraryLoad; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferInputStream.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferInputStream.java new file mode 100644 index 0000000..a48f807 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferInputStream.java @@ -0,0 +1,258 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.bytebuffer; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; + +public class ByteBufferInputStream implements ByteBufferStream { + private final InputStream in; + private byte[] buf; + private ByteBuffer bbuf; + boolean eof; + private int offset; + + private void require (int len) throws IOException { + if (bbuf.remaining() >= len) return; + int remain = bbuf.remaining(); + offset += bbuf.position(); + if (len > buf.length) { + byte[] newbuf = new byte[len]; + System.arraycopy (buf, bbuf.position(), newbuf, 0, remain); + buf = newbuf; + } else { + System.arraycopy (buf, bbuf.position(), buf, 0, remain); + } + fill_buf (remain); + while (bbuf.remaining() < len) { + if (eof) { + throw new BufferUnderflowException(); + } + fill_buf (bbuf.remaining()); + } + } + + private void fill_buf (int start) throws IOException { + if (eof) return; + int len = in.read(buf, start, buf.length - start); + if (len == -1) { + bbuf = ByteBuffer.wrap(buf, 0, 0); + eof = true; + } else { + bbuf = ByteBuffer.wrap(buf, 0, start + len); + } + } + + public ByteBufferInputStream (InputStream _in) throws IOException { + in = _in; + buf = new byte[65536]; + eof = false; + offset = 0; + fill_buf (0); + } + + public ByteBufferInputStream (InputStream _in, int init_length) throws IOException { + in = _in; + buf = new byte[init_length]; + eof = false; + offset = 0; + fill_buf (0); + } + + @Override + public ByteBufferStream clear() { + throw new UnsupportedOperationException(); + } + + @Override + public ByteBufferStream flip() { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream rewind() { + throw new UnsupportedOperationException(); + } + + @Override + public ByteBufferStream mark() { + throw new UnsupportedOperationException(); + } + + @Override + public ByteBufferStream reset() { + throw new UnsupportedOperationException(); + } + + @Override + public int capacity() { + return bbuf.capacity(); + } + + @Override + public boolean hasRemaining() throws IOException { + if (bbuf.hasRemaining()) return true; + if (eof) return false; + fill_buf (0); + return bbuf.hasRemaining(); + } + + @Override + public int remaining() throws IOException { + if (bbuf.hasRemaining()) return bbuf.remaining(); + if (eof) return 0; + fill_buf (0); + return bbuf.remaining(); + } + + @Override + public int position() { + return offset + bbuf.position(); + } + + @Override + public ByteBufferStream position(int newPosition) throws IOException { + if (newPosition < offset) { + throw new UnsupportedOperationException("position backwards"); + } + require (newPosition - position()); + bbuf.position (newPosition - offset); + return this; + } + + @Override + public byte get() throws IOException { + require (1); + return bbuf.get(); + } + + @Override + public byte get(int position) throws IOException { + require (position - (offset + bbuf.position()) + 1); + return bbuf.get(position - offset); + } + + @Override + public ByteBufferStream get(byte[] dst) throws IOException { + require (dst.length); + bbuf.get(dst); + return this; + } + + @Override + public ByteBufferStream get(byte[] dst, int offset, int length) throws IOException { + require (length); + bbuf.get (dst, offset, length); + return this; + } + + @Override + public char getChar() throws IOException { + require (2); + return bbuf.getChar(); + } + + @Override + public double getDouble() throws IOException { + require (8); + return bbuf.getDouble(); + } + + @Override + public float getFloat() throws IOException { + require (4); + return bbuf.getFloat(); + } + + @Override + public int getInt() throws IOException { + require (4); + return bbuf.getInt(); + } + + @Override + public long getLong() throws IOException { + require (8); + return bbuf.getLong(); + } + + @Override + public short getShort() throws IOException { + require (2); + return bbuf.getShort(); + } + + @Override + public short getShort(int position) throws IOException { + require (position - (offset + bbuf.position()) + 2); + return bbuf.getShort(position - offset); + } + + @Override + public ByteBufferStream put(byte b) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream put(byte[] src) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream put(byte[] src, int offset, int length) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream putChar(char value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream putDouble(double value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream putFloat(float value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream putInt(int value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream putLong(long value) { + throw new ReadOnlyBufferException(); + } + + @Override + public ByteBufferStream putShort(short value) { + throw new ReadOnlyBufferException(); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferSpace.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferSpace.java new file mode 100644 index 0000000..604856f --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferSpace.java @@ -0,0 +1,247 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.bytebuffer; + +import java.io.IOException; +import java.nio.ByteBuffer; + + +public class ByteBufferSpace implements ByteBufferStream { + private byte[] bytes; + private ByteBuffer buf; + + public ByteBufferSpace() { + bytes = new byte[32]; + buf = ByteBuffer.wrap(bytes); + } + public ByteBufferSpace(int size) { + bytes = new byte[size]; + buf = ByteBuffer.wrap(bytes); + } + + private ByteBufferSpace(byte[] bytes) { + this.bytes = bytes; + buf = ByteBuffer.wrap(bytes); + } + + public ByteBufferSpace dup() { + return new ByteBufferSpace(bytes); + } + + public void reserve (int size) { + int pos = buf.position(); + if (pos + size > buf.capacity()) { + int len = bytes.length; + while (len < pos + size) len *= 2; + byte[] oldbytes = bytes; + bytes = new byte[len]; + buf = ByteBuffer.wrap(bytes); + buf.put(oldbytes); + buf.position(pos); + } + } + + public ByteBufferSpace clear() { + buf.clear(); + return this; + } + public ByteBufferSpace flip() { + buf.flip(); + return this; + } + + public ByteBufferSpace rewind() { + buf.rewind(); + return this; + } + + public ByteBufferSpace mark() { + buf.mark(); + return this; + } + + public ByteBufferSpace reset() { + buf.reset(); + return this; + } + + public int capacity() { + return buf.capacity(); + } + + public boolean hasRemaining() { + return buf.hasRemaining(); + } + public int remaining() { + return buf.remaining(); + } + + public int position() { + return buf.position(); + } + public ByteBufferSpace position(int newPosition) { + if (newPosition > buf.position()) { + reserve (newPosition - buf.position()); + } + buf.position(newPosition); + return this; + } + + public byte get() { + return buf.get(); + } + + @Override + public byte get(int position) throws IOException { + return position(position).get(); + } + + public ByteBufferSpace get(byte[] dst) { + buf.get(dst); + return this; + } + public ByteBufferSpace get(byte[] dst, int offset, int length) { + buf.get(dst, offset, length); + return this; + } + public char getChar() { + return buf.getChar(); + } + public double getDouble() { + return buf.getDouble(); + } + public float getFloat() { + return buf.getFloat(); + } + public int getInt() { + return buf.getInt(); + } + public long getLong() { + return buf.getLong(); + } + public short getShort() { + return buf.getShort(); + } + @Override + public short getShort(int position) { + return position(position).getShort(); + } + + public ByteBufferSpace put(byte b) { + reserve(1); + buf.put(b); + return this; + } + public ByteBufferSpace put(byte[] src) { + reserve(src.length); + buf.put(src); + return this; + } + public ByteBufferSpace put(byte[] src, int offset, int length) { + reserve(length); + buf.put(src, offset, length); + return this; + } public ByteBufferSpace put(ByteBuffer src) { + reserve(src.remaining()); + buf.put(src); + return this; + } + public ByteBufferSpace putChar(char value) { + reserve(2); + buf.putChar(value); + return this; + } + public ByteBufferSpace putDouble(double value) { + reserve(8); + buf.putDouble(value); + return this; + } + public ByteBufferSpace putFloat(float value) { + reserve(4); + buf.putFloat(value); + return this; + } + public ByteBufferSpace putInt(int value) { + reserve(4); + buf.putInt(value); + return this; + } + public ByteBufferSpace putLong(long value) { + reserve(8); + buf.putLong(value); + return this; + } + public ByteBufferSpace putShort(short value) { + reserve(2); + buf.putShort(value); + return this; + } + public String toString() { + return buf.toString(); + } + + public int hashCode() { + return buf.hashCode(); + } + + public boolean equals(Object ob) { + if (! (ob instanceof ByteBufferSpace)) return false; + return buf.equals(((ByteBufferSpace) ob).buf); + } + + public void trimToSize() { + int pos = buf.position(); + byte[] oldbytes = bytes; + bytes = new byte[pos]; + buf = ByteBuffer.wrap(bytes); + buf.put(oldbytes, 0, pos); + } + + public int memSize() { + return bytes.length + 160; + } + + public static void main (String[] argv) { + ByteBufferSpace b = new ByteBufferSpace(32); + byte chk[] = new byte[2]; + chk[0] = (byte) 1; + chk[1] = (byte) 2; + for (int i=0; i<3000000; i++) { + b.put((byte) 0).put(chk).putInt(3).putShort((short) 4).putFloat((float) 5.0).putDouble(6.0); + } + System.out.println("buffer size " + b.capacity()); + b.flip(); + for (int i=0; i<3000000; i++) { + byte bchk = b.get(); + byte bchk2[] = new byte[2]; + b.get(bchk2); + int ichk = b.getInt(); + short schk = b.getShort(); + float fchk = b.getFloat(); + double dchk = b.getDouble(); + if (bchk != 0 || bchk2[0] != 1 || bchk2[1] != 2 || + ichk != 3 || schk != 4 || fchk != 5.0 || dchk != 6.0) { + System.out.println("i = " + i + ": bad data\n"); + } + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferStream.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferStream.java new file mode 100644 index 0000000..5053ac3 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferStream.java @@ -0,0 +1,57 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.bytebuffer; + +import java.io.IOException; + +public interface ByteBufferStream { + public ByteBufferStream clear() throws IOException; + public ByteBufferStream flip() throws IOException; + public ByteBufferStream rewind() throws IOException; + public ByteBufferStream mark() throws IOException; + public ByteBufferStream reset() throws IOException; + public int capacity() throws IOException; + public boolean hasRemaining() throws IOException; + public int remaining() throws IOException; + public int position() throws IOException; + public ByteBufferStream position(int newPosition) throws IOException; + public byte get() throws IOException; + public byte get(int position) throws IOException; + public ByteBufferStream get(byte[] dst) throws IOException; + public ByteBufferStream get(byte[] dst, int offset, int length) throws IOException; + public char getChar() throws IOException; + public double getDouble() throws IOException; + public float getFloat() throws IOException; + public int getInt() throws IOException; + public long getLong() throws IOException; + public short getShort() throws IOException; + public short getShort(int position) throws IOException; + public ByteBufferStream put(byte b) throws IOException; + public ByteBufferStream put(byte[] src) throws IOException; + public ByteBufferStream put(byte[] src, int offset, int length) throws IOException; + public ByteBufferStream putChar(char value) throws IOException; + public ByteBufferStream putDouble(double value) throws IOException; + public ByteBufferStream putFloat(float value) throws IOException; + public ByteBufferStream putInt(int value) throws IOException; + public ByteBufferStream putLong(long value) throws IOException; + public ByteBufferStream putShort(short value) throws IOException; +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferStreamWrap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferStreamWrap.java new file mode 100644 index 0000000..78952f7 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/bytebuffer/ByteBufferStreamWrap.java @@ -0,0 +1,200 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.bytebuffer; + +import java.nio.ByteBuffer; + + +public class ByteBufferStreamWrap implements ByteBufferStream { + private final ByteBuffer buf; + + public ByteBufferStreamWrap (ByteBuffer buf_) { + buf = buf_; + } + + @Override + public ByteBufferStream clear() { + buf.clear(); + return this; + } + + @Override + public ByteBufferStream flip() { + buf.flip(); + return this; + } + + @Override + public ByteBufferStream rewind() { + buf.rewind(); + return this; + } + + @Override + public ByteBufferStream mark () { + buf.mark(); + return this; + } + + @Override + public ByteBufferStream reset() { + buf.reset(); + return this; + } + + @Override + public int capacity() { + return buf.capacity(); + } + + @Override + public boolean hasRemaining() { + return buf.hasRemaining(); + } + + @Override + public int remaining() { + return buf.remaining(); + } + + @Override + public int position() { + return buf.position(); + } + + @Override + public ByteBufferStream position(int newPosition) { + buf.position(newPosition); + return this; + } + + @Override + public byte get() { + return buf.get(); + } + + @Override + public ByteBufferStream get(byte[] dst) { + buf.get(dst); + return this; + } + + @Override + public ByteBufferStream get(byte[] dst, int offset, int length) { + buf.get (dst, offset, length); + return this; + } + + @Override + public char getChar() { + return buf.getChar(); + } + + @Override + public double getDouble() { + return buf.getDouble(); + } + + @Override + public float getFloat() { + return buf.getFloat(); + } + + @Override + public int getInt() { + return buf.getInt(); + } + + @Override + public long getLong() { + return buf.getLong(); + } + + @Override + public short getShort() { + return buf.getShort(); + } + + @Override + public ByteBufferStream put(byte b) { + buf.put(b); + return this; + } + + @Override + public ByteBufferStream put(byte[] src) { + buf.put(src); + return this; + } + + @Override + public ByteBufferStream put(byte[] src, int offset, int length) { + buf.put(src, offset, length); + return this; + } + + @Override + public ByteBufferStream putChar(char value) { + buf.putChar(value); + return this; + } + + @Override + public ByteBufferStream putDouble(double value) { + buf.putDouble(value); + return this; + } + + @Override + public ByteBufferStream putFloat(float value) { + buf.putFloat(value); + return this; + } + + @Override + public ByteBufferStream putInt(int value) { + buf.putInt(value); + return this; + } + + @Override + public ByteBufferStream putLong(long value) { + buf.putLong(value); + return this; + } + + @Override + public ByteBufferStream putShort(short value) { + buf.putShort(value); + return this; + } + + @Override + public byte get(int position) { + return buf.get(position); + } + + @Override + public short getShort(int position) { + return buf.getShort(position); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/CacheBuilder.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/CacheBuilder.java new file mode 100644 index 0000000..85adc49 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/CacheBuilder.java @@ -0,0 +1,28 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.cache; + +public interface CacheBuilder<Key, Value> { + public Value build(Key k); + public long memSize(Value v); + public boolean validate(Key k, Value v); +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/SimpleCache.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/SimpleCache.java new file mode 100644 index 0000000..3a4d99a --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/SimpleCache.java @@ -0,0 +1,1039 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.cache; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.lang.management.ManagementFactory; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.apache.log4j.Logger; + +public class SimpleCache<Key, Value, Builder extends CacheBuilder<Key,Value>> + implements SimpleCacheMBean<Key, Value, Builder> { + + private static final Logger logger = Logger.getLogger("org.openecomp.ncomp.utils.simplecache"); + + private static final String defaultProperties = + "simplecache.default.cache.maxentries=10\n" + + "simplecache.default.cache.maxage=-1\n" + + "simplecache.default.cache.maxMemSize=-1\n" + + "simplecache.default.ready.maxentries=1\n" + + "simplecache.default.ready.maxage=3600000\n" + + "simplecache.default.ready.maxMemSize=-1\n" + + "simplecache.default.prefetch.threads=0\n" + + "simplecache.Topology.cache.maxentries=30\n" + + "simplecache.LsaMonitor.cache.maxentries=300\n" + + "simplecache.LsaMonitor.ready.maxentries=100\n" + + "simplecache.LsaMonitor.ready.maxage=60000\n" + + "simplecache.LsaMonitor.prefetch.threadname=LsaCachePrefetch\n" + + "simplecache.LsaMonitor.prefetch.threads=20\n" + + "simplecache.OspfNetwork.cache.maxentries=10\n"; + + private static final Properties cacheProperties = loadProperties(); + + public enum EntryStateEnum { + /** + * An entry which has been created, but not yet on any list. + */ + NEW_ENTRY(0, "New Entry"), + + /** + * An entry waiting for preFetch, on prefetchList + */ + PREFETCH_ON_QUEUE(1, "Prefetch On Queue"), + + /** + * An entry being built by prefetch, on buildingPrefetchList + */ + PREFETCH_RUNNING(3, "Prefetch Running"), + + /** + * An entry that has been prefetched, but not yet used, on readyList + */ + PREFETCH_READY(5, "Prefetch Ready"), + + + /** + * An entry being built (from Get, not Prefetch), on buildingGetList + */ + BUILD_RUNNING(7, "Build Running"), + + /** + * An entry in the cache, that has been used, on cacheList + */ + CACHED(9, "Cached"), + + /** + * An entry that has been removed from the active cache. + * This is currently not used, but available for future cache miss tracking. + */ + DEAD(10, "Dead"), + + /** + * An entry for which build failed, on failedList. + * This acts like an entry that doesn't exist, except that it + * tracks failures. + */ + FAILED(11, "Failed"); + + private final int value; + private final String name; + + private EntryStateEnum(int value, String name) { + this.value = value; + this.name = name; + } + + public int getValue() { + return value; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + } //EntryStateEnum + + private class Entry { + public EntryStateEnum state; + public Date lastUsed; + public int age; + public final Key key; + public Value value; + public Entry next; + public Entry prev; + public long memSize; + public Entry (Key key) { + logger.debug("Entry() New entry " + key); + state = EntryStateEnum.NEW_ENTRY; + lastUsed = null; + age = cacheAge; + this.key = key; + value = null; + next = null; + prev = null; + memSize = 0; + } + } + + private class EntryList implements Iterable<Entry> { + private final Entry listDummy; + private int size; + private int maxsize; + private long memSize; + private long maxMemSize; + private long maxage; + + private class EntryIterator implements Iterator<Entry> { + private Entry e; + + public EntryIterator () { + e = listDummy; + } + + @Override + public boolean hasNext() { + return (e.next != listDummy); + } + + @Override + public Entry next() { + e = e.next; + return e; + } + + @Override + public void remove() { + Entry e_save = e; + e = e.prev; + EntryList.this.remove(e_save); + } + } + + public EntryList () { + this(-1); + } + + public EntryList (int maxsize) { + listDummy = new Entry(null); + listDummy.next = listDummy; + listDummy.prev = listDummy; + size = 0; + this.maxsize = maxsize; + memSize = 0; + maxMemSize = -1; + maxage = -1; + } + + public void addToFront (Entry e) { + e.next = listDummy.next; + e.prev = listDummy; + listDummy.next.prev = e; + listDummy.next = e; + size++; + memSize += e.memSize; + } + + public void addToBack (Entry e) { + e.next = listDummy; + e.prev = listDummy.prev; + listDummy.prev.next = e; + listDummy.prev = e; + size++; + memSize += e.memSize; + } + + public void remove (Entry e) { + e.next.prev = e.prev; + e.prev.next = e.next; + e.prev = null; + e.next = null; + size--; + memSize -= e.memSize; + } + + public void moveToFront (Entry e) { + remove (e); + addToFront (e); + } + + @SuppressWarnings("unused") + public void moveToBack (Entry e) { + remove (e); + addToBack (e); + } + + public Entry getFront () { + if (listDummy.next == listDummy) return null; + return listDummy.next; + } + + public Entry getBack () { + if (listDummy.prev == listDummy) return null; + return listDummy.prev; + } + + public Entry getOverflow (Entry space) { + boolean full = ((space == null) ? isOverFull(0,0) : isOverFull(1,space.memSize)); + if (full) return getBack(); + if (maxage >= 0) { + Entry e = getBack(); + if (e == null) return null; + Date d = new Date(); + d.setTime(d.getTime()-maxage); + if (e.lastUsed.before(d)) return e; + } + return null; + } + + public int size () { + return size; + } + + public long memSize() { + return memSize; + } + + public boolean isEmpty() { + return (listDummy.next == listDummy); + } + + public void setMaxSize (int maxsize) { + this.maxsize = maxsize; + } + + public void setMaxMemSize (long maxMemSize) { + this.maxMemSize = maxMemSize; + } + + public int getMaxSize () { + return maxsize; + } + + public long getMaxMemSize () { + return maxMemSize; + } + + public boolean isOverFull(int extraCnt, long extraMem) { + return ((maxsize >= 0 && size + extraCnt > maxsize) || + (maxMemSize >= 0 && memSize + extraMem > maxMemSize)); + } + + public void setMaxAge (long maxage) { + this.maxage = maxage; + } + + public long getMaxAge () { + return maxage; + } + + public boolean add (Entry e) { + addToBack (e); + return true; + } + + public Entry poll () { + Entry e = getFront(); + remove (e); + return e; + } + + + @Override + public Iterator<Entry> iterator() { + return new EntryIterator(); + } + + public String[] getEntries() { + String[] entrylist = new String[size()]; + int i = 0; + synchronized (SimpleCache.this) { + for (Entry e : this) { + entrylist[i++] = e.key.toString(); + } + } + return entrylist; + } + + } + + private class PrefetchThread extends Thread { + private final int num; + + public PrefetchThread (ThreadGroup group, int num_) { + super(group, group.getName() + "_" + num_); + num = num_; + setDaemon(true); + } + + public void run() { + for (;;) { + Entry e = null; + synchronized (SimpleCache.this) { + while (num < numthreads && (prefetchList.isEmpty() || readyList.isOverFull(buildingPrefetchList.size()+1,0))) { + try { + SimpleCache.this.wait(); + } catch (InterruptedException e1) { + // ignore + } + } + if (num >= numthreads) return; + e = prefetchList.poll(); + logger.debug("prefetch thread got " + e.key + " state " + e.state.getName() + " -> PREFETCH_RUNNING"); + e.state = EntryStateEnum.PREFETCH_RUNNING; + buildingPrefetchList.add(e); + } + buildEntryPrefetch (e); + } + } + } + + private final String name; + private final Map<Key,Entry> cache; + private int cacheAge; + private final Builder builder; + private final EntryList prefetchList; + private final EntryList buildingPrefetchList; + private final EntryList buildingGetList; + private final EntryList cacheList; + private final EntryList readyList; + private final EntryList failedList; + private int cacheQueries; + private int cacheHits; + private int cacheHitPrefetch; + private int cacheBuilt; + private int prefetchQueries; + private int prefetchHits; + private int prefetchBuilt; + private int buildFailed; + private int validateFailed; +// private final EntryList deadList; + private int numthreads; + private final ThreadGroup prefetchGroup; + private final ArrayList<PrefetchThread> prefetchThreads; + + public SimpleCache (String name, Builder builder) { + this.name = name; + cache = new HashMap<Key,Entry>(); + this.builder = builder; + cacheList = new EntryList(getPropertyInt("cache.maxentries", 10)); + cacheList.setMaxAge(getPropertyLong("cache.maxage", -1)); + cacheList.setMaxMemSize(getPropertyLong("cache.maxMemSize", -1)); + readyList = new EntryList(getPropertyInt("ready.maxentries", 1)); + readyList.setMaxAge(getPropertyLong("ready.maxage", 3600000)); + readyList.setMaxMemSize(getPropertyLong("ready.maxMemSize", -1)); + failedList = new EntryList(getPropertyInt("failed.maxentries", 1000)); + prefetchList = new EntryList(); + buildingPrefetchList = new EntryList(); + buildingGetList = new EntryList(); + resetCounters(); +// deadList = new EntryList(); + this.numthreads = getPropertyInt("prefetch.threads", 0); + String threadname = getProperty("prefetch.threadname"); + if (threadname == null) threadname = name + "PrefetchThread"; + prefetchGroup = new ThreadGroup (threadname); + prefetchThreads = new ArrayList<PrefetchThread>(numthreads); + for (int i=0; i<numthreads; i++) { + PrefetchThread t = new PrefetchThread (prefetchGroup, i); + prefetchThreads.add(t); + t.start(); + } + } + + private static URL getResource (String resource) { + URL ret = null; + + if (resource == null) return null; + try { + ret = new URL(resource); + } catch (MalformedURLException e) { + logger.debug("Malformed url" + resource); + } + if (ret != null) return ret; + ret = SimpleCache.class.getResource(resource); + if (ret != null) return ret; + ret = SimpleCache.class.getClassLoader().getResource (resource); + if (ret != null) return ret; + ret = ClassLoader.getSystemResource(resource); + return ret; + } + + private static Properties loadProperties () { + Properties defaultProps = new Properties(); + try { + defaultProps.load(new StringReader(defaultProperties)); + } catch (IOException e1) { + logger.error("IOException while reading default properties"); + } + Properties properties = new Properties(defaultProps); + String property_name = System.getProperty("simplecache.configuration","simplecache.properties"); + URL prop_resource = getResource (property_name); + InputStream property_stream = null; + + if (prop_resource != null) { + try { + property_stream = prop_resource.openStream(); + } catch (IOException e1) { + logger.error("IOException while opening property_stream"); + } + } + if (property_stream != null) { + try { + properties.load(property_stream); + } catch (IOException e) { + logger.error("IO Exception loading properties"); + } + } + return properties; + } + + private String getProperty(String pname) { + String val = cacheProperties.getProperty("simplecache." + name + "." + pname); + if (val != null) return val; + return cacheProperties.getProperty("simplecache.default." + pname); + } + + @SuppressWarnings("unused") + private String getProperty(String pname, String def) { + String val = cacheProperties.getProperty("simplecache." + name + "." + pname); + if (val != null) return val; + return cacheProperties.getProperty("simplecache.default." + pname, def); + } + + private int getPropertyInt(String pname, int def) { + String val = cacheProperties.getProperty("simplecache." + name + "." + pname); + if (val != null) return Integer.parseInt(val); + val = cacheProperties.getProperty("simplecache.default." + pname); + if (val != null) return Integer.parseInt(val); + return def; + } + + private long getPropertyLong(String pname, long def) { + String val = cacheProperties.getProperty("simplecache." + name + "." + pname); + if (val != null) return Long.parseLong(val); + val = cacheProperties.getProperty("simplecache.default." + pname); + if (val != null) return Long.parseLong(val); + return def; + } + + public ObjectName registerMBean (String domain) throws Exception { + String basename = domain + ":type=SimpleCache,name=" + name; + ObjectName objectName = new ObjectName(basename); + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbs.registerMBean(this, objectName); + return objectName; + } + + public ObjectName registerMBeanMultiple (String domain) throws Exception { + String basename = domain + ":type=SimpleCache,name=" + name; + ObjectName objectName = new ObjectName(basename); + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + int cnt = 0; + synchronized (this.getClass()) { + while (mbs.isRegistered(objectName)) { + cnt++; + objectName = new ObjectName(basename + "_" + cnt); + } + mbs.registerMBean(this, objectName); + } + return objectName; + } + + public void unregisterMBean (ObjectName name) throws MBeanRegistrationException, InstanceNotFoundException { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbs.unregisterMBean(name); + } + + private void buildEntryPrefetch (Entry e) { + synchronized (e) { + if (e.state != EntryStateEnum.PREFETCH_RUNNING) { + logger.warn("Prefetch build stolen for " + e.key.toString()); + return; + } + boolean failed = false; + try { + logger.debug("buildEntryPrefetch build " + e.key); + e.value = builder.build(e.key); + } catch (Exception ex) { + logger.error("Failure for prefetch building " + e.key.toString(), ex); + failed = true; + e.value = null; + } + long memSize = (e.value == null) ? 0 : builder.memSize(e.value); + synchronized (this) { + if (e.state != EntryStateEnum.PREFETCH_RUNNING) { + throw new RuntimeException("Prefetch build status changed for " + e.key.toString()); + } + if (failed) { + buildingPrefetchList.remove(e); + e.state = EntryStateEnum.FAILED; + pruneList(failedList, e, "failedList"); + failedList.addToFront(e); + buildFailed++; + return; + } + logger.debug("buildEntryPrefetch state " + e.key + " " + e.state.getName() + " -> PREFETCH_READY"); + buildingPrefetchList.remove(e); + e.state = EntryStateEnum.PREFETCH_READY; + e.lastUsed = new Date(); + e.memSize = memSize; + pruneList(readyList, e, "readyList"); + readyList.addToFront (e); + this.notifyAll(); + prefetchBuilt++; + } + } + } + + private Value buildEntry (Entry e) { + synchronized (e) { + synchronized (this) { + switch (e.state) { + case NEW_ENTRY: + logger.debug("buildEntry state " + e.key + " NEW_ENTRY -> BUILD_RUNNING"); + e.state = EntryStateEnum.BUILD_RUNNING; + buildingGetList.add(e); + break; + case PREFETCH_ON_QUEUE: + logger.debug("buildEntry state " + e.key + " PREFETCH_ON_QUEUE -> BUILD_RUNNING"); + prefetchList.remove(e); + e.state = EntryStateEnum.BUILD_RUNNING; + buildingGetList.add(e); + break; + case BUILD_RUNNING: + logger.debug("buildEntry state " + e.key + " BUILD_RUNNING"); + break; + case PREFETCH_RUNNING: + logger.debug("buildEntry state " + e.key + " PREFETCH_RUNNING -> BUILD_RUNNING"); + buildingPrefetchList.remove(e); + e.state = EntryStateEnum.BUILD_RUNNING; + buildingGetList.add(e); + break; + case CACHED: + if (builder.validate(e.key, e.value)) { + logger.debug("buildEntry state " + e.key + " CACHED"); + e.lastUsed = new Date(); + cacheList.moveToFront(e); + cacheHits++; + return e.value; + } else { + logger.debug("buildEntry state " + e.key + " CACHED but failed validate"); + cacheList.remove(e); + e.value = null; + e.lastUsed = new Date(); + e.state = EntryStateEnum.BUILD_RUNNING; + buildingGetList.add(e); + validateFailed++; + break; + } + case PREFETCH_READY: + if (builder.validate(e.key, e.value)) { + logger.debug("buildEntry state " + e.key + " PREFETCH_READY -> CACHED"); + readyList.remove(e); + e.lastUsed = new Date(); + e.state = EntryStateEnum.CACHED; + pruneList (cacheList, e, "cacheList"); + cacheList.addToFront(e); + cacheHitPrefetch++; + this.notifyAll(); + return e.value; + } else { + logger.debug("buildEntry state " + e.key + " PREFETCH_READY but failed validate"); + readyList.remove(e); + e.lastUsed = new Date(); + e.value = null; + e.state = EntryStateEnum.BUILD_RUNNING; + buildingGetList.add(e); + validateFailed++; + this.notifyAll(); + break; + } + default: + throw new RuntimeException("Unexpected get state " + e.state.toString() + " for " + e.key.toString()); + } + } + Value v; + String failure = null; + try { + logger.debug("buildEntry build " + e.key); + v = builder.build(e.key); + } catch (Exception ex) { + logger.error("Failure for get building " + e.key.toString(), ex); + failure = ex.getMessage(); + v = null; + } + e.value = v; + long memSize = (v == null) ? 0 : builder.memSize(v); + synchronized (this) { + if (e.state != EntryStateEnum.BUILD_RUNNING) { + logger.error("Get build status changed for " + e.key.toString()); + } + if (failure != null) { + buildingGetList.remove(e); + pruneList(failedList, e, "failedList"); + e.state = EntryStateEnum.FAILED; + failedList.addToFront(e); + buildFailed++; + throw new RuntimeException("Simple cache build failed: " + failure); + } + logger.debug("buildEntry state " + e.key + " " + e.state.getName() + " -> CACHED"); + buildingGetList.remove(e); + e.state = EntryStateEnum.CACHED; + e.lastUsed = new Date(); + e.memSize = memSize; + pruneList (cacheList, e, "cacheList"); + cacheList.addToFront (e); + cacheBuilt++; + } + return v; + } + } + + private int pruneList (EntryList l, Entry space, String listName) { + int ret = 0; + Entry e = l.getOverflow(space); + while (e != null) { + logger.debug("pruneList pruned " + listName + " " + e.key + " state " + e.state.getName()); + l.remove(e); + cache.remove(e.key); + ret++; + e = l.getOverflow(space); + } + return ret; + } + + public void preFetch (Key k) { + if (numthreads == 0) return; + Entry e; + synchronized (this) { + prefetchQueries++; + e = cache.get(k); + if (e != null && e.state != EntryStateEnum.FAILED) { + logger.debug("preFetch " + k + " hit"); + prefetchHits++; + return; + } + logger.debug("preFetch " + k + " miss, state -> PREFETCH_ON_QUEUE"); + if (e == null) { + e = new Entry (k); + cache.put(k, e); + } else { + failedList.remove(e); + } + e.state = EntryStateEnum.PREFETCH_ON_QUEUE; + prefetchList.add(e); + this.notifyAll(); + } + } + + public Value get (Key k) { + Entry e; + synchronized (this) { + cacheQueries++; + e = cache.get(k); + if (e != null && e.state != EntryStateEnum.FAILED) { + logger.debug("get " + k + " hit, state = " + e.state.getName()); + } else { + logger.debug("get " + k + " miss, state -> BUILD_RUNNING"); + if (e == null) { + e = new Entry (k); + cache.put(k, e); + } else { + failedList.remove(e); + } + e.state = EntryStateEnum.BUILD_RUNNING; + buildingGetList.add(e); + } + } + return buildEntry(e); + } + + @Override + public int getMaxEntries() { + return cacheList.getMaxSize(); + } + + @Override + public void setMaxEntries(int maxsize) { + synchronized (this) { + cacheList.setMaxSize (maxsize); + pruneList(cacheList, null, "cacheList"); + } + } + + @Override + public int getNumEntries() { + return cacheList.size(); + } + + @Override + public long getMaxMemSize() { + return cacheList.getMaxMemSize(); + } + + @Override + public void setMaxMemSize(long maxMemSize) { + synchronized (this) { + cacheList.setMaxMemSize(maxMemSize); + pruneList(cacheList, null, "cacheList"); + } + } + + @Override + public long getMemSize() { + return cacheList.memSize(); + } + + @Override + public long getMaxEntryAge() { + return cacheList.getMaxAge(); + } + + @Override + public void setMaxEntryAge(long age) { + synchronized (this) { + cacheList.setMaxAge(age); + pruneList(cacheList, null, "cacheList"); + } + } + + @Override + public String[] getEntries() { + synchronized (this) { + return cacheList.getEntries(); + } + } + + @Override + public String[] getEntriesDetailed() { + synchronized (this) { + String[] entrylist = new String[cache.size()]; + int i = 0; + for (Map.Entry<Key,Entry> me : cache.entrySet()) { + Entry e = me.getValue(); + entrylist[i++] = e.state.toString() + "|" + e.key.toString() + "|" + e.lastUsed + "|" + e.age; + } + Arrays.sort(entrylist); + return entrylist; + } + } + + @Override + public int getMaxPendingEntries() { + return readyList.getMaxSize(); + } + + @Override + public void setMaxPendingEntries(int maxsize) { + synchronized (this) { + readyList.setMaxSize(maxsize); + if (pruneList(readyList, null, "readyList") > 0) this.notifyAll(); + } + } + + @Override + public long getMaxPendingMemSize() { + return readyList.getMaxMemSize(); + } + + @Override + public void setMaxPendingMemSize(long maxMemSize) { + synchronized (this) { + readyList.setMaxMemSize(maxMemSize); + if (pruneList(readyList, null, "readyList") > 0) this.notifyAll(); + } + } + + @Override + public int getNumPendingEntries() { + return readyList.size(); + } + + @Override + public long getPendingMemSize() { + return readyList.memSize(); + } + + @Override + public long getMaxPendingEntryAge() { + return readyList.getMaxAge(); + } + + @Override + public void setMaxPendingEntryAge(long age) { + synchronized (this) { + readyList.setMaxAge(age); + if (pruneList(readyList, null, "readyList") > 0) this.notifyAll(); + } + } + + @Override + public String[] getPendingEntries() { + synchronized (this) { + return readyList.getEntries(); + } + } + + @Override + public int getNumPrefetchQueued() { + return prefetchList.size(); + } + + @Override + public String[] getPrefetchQueuedEntries() { + synchronized (this) { + return prefetchList.getEntries(); + } + } + + @Override + public int getNumBuildingPrefetch() { + return buildingPrefetchList.size(); + } + + @Override + public String[] getBuildingPrefetchEntries() { + synchronized (this) { + return buildingPrefetchList.getEntries(); + } + } + + @Override + public int getNumBuildingGet() { + return buildingGetList.size(); + } + + @Override + public String[] getBuildingGetEntries() { + synchronized (this) { + return buildingGetList.getEntries(); + } + } + + @Override + public int getMaxFailedEntries() { + return failedList.getMaxSize(); + } + + @Override + public int getNumFailedEntries() { + return failedList.size(); + } + + @Override + public void setMaxFailedEntries(int maxsize) { + synchronized (this) { + failedList.setMaxSize (maxsize); + pruneList(failedList, null, "failedList"); + } + } + + @Override + public String[] getFailedEntries() { + synchronized (this) { + return failedList.getEntries(); + } + } + + @Override + public int getNumThreads () { + return numthreads; + } + + @Override + public void setNumThreads(int n) { + if (n < 0) n = 0; + synchronized (prefetchThreads) { + int oldnumthreads = numthreads; + synchronized (this) { + numthreads = n; + this.notifyAll(); + } + if (numthreads < oldnumthreads) { + while (prefetchThreads.size() > numthreads) { + PrefetchThread t = prefetchThreads.remove(prefetchThreads.size()-1); + boolean joined = false; + while (!joined) { + try { + t.join(); + joined = true; + } catch (InterruptedException e) { + } + } + } + } else if (numthreads > oldnumthreads) { + for (int i=oldnumthreads; i<numthreads; i++) { + PrefetchThread t = new PrefetchThread (prefetchGroup, i); + prefetchThreads.add(t); + t.start(); + } + } + } + } + + @Override + public int getActiveThreadCount() { + return prefetchGroup.activeCount(); + } + + @Override + public String[] getThreadNames() { + String[] names = new String[prefetchThreads.size()]; + synchronized (prefetchThreads) { + for (int i=0; i<prefetchThreads.size(); ++i) { + names[i] = prefetchThreads.get(i).getName(); + } + } + return names; + } + + @Override + public void resetCounters() { + cacheQueries = 0; + cacheHits = 0; + cacheHitPrefetch = 0; + cacheBuilt = 0; + prefetchQueries = 0; + prefetchHits = 0; + prefetchBuilt = 0; + buildFailed = 0; + validateFailed = 0; + } + + @Override + public void flushCache() { + synchronized (this) { + int old_max = cacheList.getMaxSize(); + cacheList.setMaxSize (0); + pruneList(cacheList, null, "cacheList"); + cacheList.setMaxSize(old_max); + old_max = failedList.getMaxSize(); + failedList.setMaxSize(0); + pruneList(failedList, null, "failedList"); + failedList.setMaxSize(old_max); + } + } + + @Override + public int getCacheQueries() { + return cacheQueries; + } + + @Override + public int getCacheHits() { + return cacheHits; + } + + @Override + public int getCacheHitPrefetch() { + return cacheHitPrefetch; + } + + @Override + public int getBuildFailed() { + return buildFailed; + } + + @Override + public int getValidateFailed() { + return validateFailed; + } + + @Override + public int getCacheBuilt() { + return cacheBuilt; + } + + @Override + public int getPrefetchQueries() { + return prefetchQueries; + } + + @Override + public int getPrefetchHits() { + return prefetchHits; + } + + @Override + public int getPrefetchBuilt() { + return prefetchBuilt; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/SimpleCacheMBean.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/SimpleCacheMBean.java new file mode 100644 index 0000000..ca19009 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/cache/SimpleCacheMBean.java @@ -0,0 +1,78 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.cache; + +public interface SimpleCacheMBean<Key,Value,Builder extends CacheBuilder<Key,Value>> { + public int getMaxEntries(); + public void setMaxEntries (int maxsize); + public long getMaxEntryAge(); + public void setMaxEntryAge (long age); + public long getMaxMemSize(); + public void setMaxMemSize(long maxMemSize); + + public int getMaxPendingEntries(); + public void setMaxPendingEntries (int maxsize); + public long getMaxPendingEntryAge(); + public void setMaxPendingEntryAge (long age); + public long getMaxPendingMemSize(); + public void setMaxPendingMemSize(long maxMemSize); + + public int getMaxFailedEntries(); + public void setMaxFailedEntries(int maxsize); + public int getNumFailedEntries(); + public String[] getFailedEntries(); + + public int getBuildFailed(); + public int getValidateFailed(); + + public void setNumThreads (int n); + public int getNumThreads (); + public int getActiveThreadCount (); + + public int getNumEntries(); + public int getNumPendingEntries(); + public int getNumPrefetchQueued(); + public int getNumBuildingPrefetch(); + public int getNumBuildingGet(); + public long getMemSize(); + public long getPendingMemSize(); + + public void resetCounters(); + public void flushCache(); + + public int getCacheQueries(); + public int getCacheHits(); + public int getCacheHitPrefetch(); + public int getCacheBuilt(); + public int getPrefetchQueries(); + public int getPrefetchHits(); + public int getPrefetchBuilt(); + + public String[] getEntries(); + public String[] getPendingEntries(); + public String[] getPrefetchQueuedEntries(); + public String[] getBuildingPrefetchEntries(); + public String[] getBuildingGetEntries(); + + public String[] getEntriesDetailed(); + public String[] getThreadNames (); +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/Commands.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/Commands.java new file mode 100644 index 0000000..758352c --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/Commands.java @@ -0,0 +1,141 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.commands; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +public class Commands { + private class Command { + private final Exec cmd; + private final String label; + private final String description; + + public Command (Exec cmd, String label, String description) { + this.cmd = cmd; + this.label = label; + this.description = description; + } + public String description () { + return description; + } + public String label () { + return label; + } + public void execute (List<String> argv) throws Exception { + String errmsg = cmd.execute(argv); + if (errmsg != null) error (errmsg); + } + public void error (String msg) { + err.print(label()); + err.print(": "); + err.println(msg); + err.print("Syntax: "); + err.println(description()); + } + public boolean matches (String s) { + return s.startsWith(label()); + } + public boolean argc_ok (int argc) { + return ((argc >= cmd.min_args()) && (cmd.max_args() == -1 || argc <= cmd.max_args())); + } + } + + List<Command> cmdlist; + PrintStream err; + PrintStream help; + + public ExecImpl cmdHelp; + public ExecImpl cmdNest; + public Commands () { + cmdlist = new ArrayList<Command>(); + err = System.err; + help = System.out; + cmdHelp = new ExecImpl(0) { + public String execute (List<String> argv) { + Commands.this.help(); + return null; + } + }; + cmdNest = new ExecImpl(1,-1) { + public String execute(List<String> argv) throws Exception { + Commands.this.execute (argv); + return null; + } + }; + } + public void add (Command cmd) { + cmdlist.add(cmd); + } + public void add (Exec cmd, String label, String description) { + cmdlist.add(new Command(cmd, label, description)); + } + public void execute (List<String> argv) throws Exception { + if (argv.isEmpty()) return; + String cmd = argv.get(0); + argv = argv.subList(1,argv.size()); + for (Command c : cmdlist) { + if (c.matches(cmd)) { + if (!c.argc_ok (argv.size())) { + c.error("Wrong number of arguments"); + return; + } + c.execute (argv); + return; + } + } + if (err != null) err.println ("Invalid command: " + cmd); + help(); + } + public void help () { + if (help == null) return; + help.println("Commands:"); + for (Command c : cmdlist) { + if (c.description().startsWith(c.label())) { + help.print(c.label()); + help.print("|"); + help.println(c.description().substring(c.label().length())); + } else { + help.print(c.label()); + help.print(" "); + help.println(c.description()); + } + } + } + public void set_err_stream (PrintStream p) { + err = p; + } + public PrintStream get_err_stream () { + return err; + } + public void set_help_stream (PrintStream p) { + help = p; + } + public PrintStream get_help_stream () { + return help; + } + public void set_streams (PrintStream err, PrintStream help) { + this.err = err; + this.help = help; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/Exec.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/Exec.java new file mode 100644 index 0000000..1308c30 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/Exec.java @@ -0,0 +1,30 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.commands; + +import java.util.List; + +public interface Exec { + int min_args (); + int max_args (); + String execute (List<String> argv) throws Exception; +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/ExecImpl.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/ExecImpl.java new file mode 100644 index 0000000..f7c7014 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/commands/ExecImpl.java @@ -0,0 +1,44 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.commands; + +import java.util.List; + +public abstract class ExecImpl implements Exec { + int min_args; + int max_args; + + public ExecImpl(int min_args, int max_args) { + this.min_args = min_args; + this.max_args = max_args; + } + public ExecImpl(int min_args) { + this(min_args, min_args); + } + public ExecImpl() { + this(0,-1); + } + public int min_args() {return min_args;} + public int max_args() {return max_args;} + + abstract public String execute(List<String> argv) throws Exception; +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/ELookupMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/ELookupMap.java new file mode 100644 index 0000000..3e4ff9e --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/ELookupMap.java @@ -0,0 +1,82 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.util.HashMap; + +import org.eclipse.emf.ecore.EObject; + + +public class ELookupMap<T extends EObject> { + private HashMap<String,T> map = new HashMap<String,T>(); + private boolean ignoreCase = false; + public boolean isIgnoreCase() { + return ignoreCase; + } + public void setIgnoreCase(boolean ignoreCase) { + this.ignoreCase = ignoreCase; + } + int featureId; + int featureId1[] = null; + int featureId2[][] = null; + EUtils<T> util = new EUtils<T>(null); + public ELookupMap(int featureIdX) { + featureId = featureIdX; + } + public ELookupMap(int featureIdX[]) { + featureId1 = featureIdX; + } + public T get(String str) { + if (ignoreCase) str = str.toLowerCase(); + return map.get(str); + } + public void add(T e) { + String key; + if (featureId2 != null) { + key = util.ecore2str(e, featureId2); + } + else if (featureId1 != null) { + key = util.ecore2str(e, featureId1); + } + else { + key = util.ecore2str(e, featureId); + } + if (ignoreCase) key = key.toLowerCase(); + if (map.get(key) != null) throw new RuntimeException("ELookupMap: adding object with existing key;" + key); + map.put(key, e); + } + public T get(int s) { + return get(Integer.toString(s)); + } + public T get(EObject o, String s) { + return get(o.toString()+ util.delim[0] + s); + } + public T get(String s, EObject o) { + return get(s + util.delim[0] + o.toString()); + } + public T get(String s, String s1) { + return get(s + util.delim[0] + s1); + } + public int size() { + return map.size(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EReader.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EReader.java new file mode 100644 index 0000000..fda7f13 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EReader.java @@ -0,0 +1,118 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import org.eclipse.emf.ecore.EObject; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class EReader<T extends EObject> implements Iterator<T>, Iterable<T> { + private EStringUtil<T> util = null; + private BufferedReader reader; + private String fileName; + private String line; + private T e = null; + + public EReader(String fileName2, EStringUtil<T> u, boolean isFilename) { + util = u; + fileName = fileName2; + if (isFilename) + reader = FileUtils.filename2reader(fileName2, u.errors); + else + reader = FileUtils.cmd2reader(fileName2); + } + public EReader(String fileName2, EStringUtil<T> u) { + util = u; + fileName = fileName2; + reader = FileUtils.filename2reader(fileName2, u.errors); + } + + public EReader(File file, EStringUtil<T> u) { + util = u; + fileName = file.getName(); + reader = FileUtils.filename2reader(fileName, u.errors); + } + + /** + * + * @return An T object for the next line (null if empty). Note the object is + * not a new object. Uses EcoreUtils.copy if needed. + */ + private T findNext() { + line = null; + try { + if (reader == null) + return null; + line = reader.readLine(); + if (line == null) { + reader.close(); + reader = null; + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (line == null) + return null; + try { + return util.str2ecore(line); + } catch (Exception e) { + throw new RuntimeException("Read error in " + fileName + " : " + e); + } + } + + public String getFileName() { + return fileName; + } + @Override + public boolean hasNext() { + if (e != null) return true; + e = findNext(); + // TODO Auto-generated method stub + return e != null; + } + @Override + public void remove() { + throw new RuntimeException("Can not remove from a reader"); + } + @Override + public T next() { + if (e != null) { + T ee = e; + e = null; + return ee; + } + return findNext(); + } + @Override + public Iterator<T> iterator() { + return this; + } + public String getLine() { + return line; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EStringUtil.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EStringUtil.java new file mode 100644 index 0000000..68681f3 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EStringUtil.java @@ -0,0 +1,238 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.List; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EcoreFactory; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.openecomp.ncomp.webservice.utils.ErrorMap; +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class EStringUtil<T extends EObject> { + private ResourceSet resourceSet; + private EPackage p; + private boolean lenient; + public boolean isLenient() { + return lenient; + } + + public void setLenient(boolean lenient) { + this.lenient = lenient; + } + + protected T sample; + private EAttribute ignoreAttr = EcoreFactory.eINSTANCE.createEAttribute(); + public ErrorMap errors; + EList<EAttribute> featureList; + + public void setFeatureMap(int id) { + featureList.clear(); + featureList.add((EAttribute) sample.eClass().getEStructuralFeature(id)); + } + + public void setFeatureMap(int ids[]) { + featureList.clear(); + for (int id : ids) { + if (id == 0) + featureList.add(ignoreAttr); + else + featureList.add((EAttribute) sample.eClass().getEStructuralFeature(id)); + } + } + + public EStringUtil(T sample1, ErrorMap errors1) { + sample = sample1; + errors = errors1; + if (sample == null) + throw new RuntimeException("Sample can not be null"); + p = sample.eClass().getEPackage(); + if (p != null && resourceSet == null) { + resourceSet = new ResourceSetImpl(); + resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put( + Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl()); + resourceSet.getPackageRegistry().put(p.getNsPrefix(), p.getEFactoryInstance()); + } + featureList = new BasicEList<EAttribute>(); + for (EAttribute attr : sample.eClass().getEAllAttributes()) { + featureList.add(attr); + } + } + + protected String[] delim = { "|", "%", "@" }; + private String[] delimRegexp = { "\\|", "%", "@" }; + + public void setDelim(String[] delim) { + this.delim = delim; + delimRegexp = new String[delim.length]; + int i = 0; + for (String s : delim) { + String ss = s; + if (s.equals("|")) + ss = "\\|"; + delimRegexp[i++] = ss; + } + } + + @SuppressWarnings("unchecked") + public String ecore2str(T e) { + StringBuffer res = new StringBuffer(); + boolean first = true; + for (EAttribute attr : featureList) { + if (first) first = false; + else res.append(delim[0]); + if (attr == ignoreAttr) + res.append(""); + else + if (e.eGet(attr) == null) + res.append(""); + else + if (attr.getUpperBound()==-1) { + List<Object> l = (List<Object>) e.eGet(attr); + boolean first1 = true; + for (Object value : l) { + if (first1) first1 = false; + else res.append(delim[1]); + res.append(value.toString()); + } + } + else + res.append(e.eGet(attr).toString()); + } + return res.toString(); + } + + String ecore2str(T e, int[][] i) { + throw new RuntimeException("TODO"); + } + + public String ecorelist2str(List<T> list) { + StringBuffer buf = new StringBuffer(); + boolean first = true; + for (T e : list) { + if (!first) { + buf.append(":"); + } + first = false; + buf.append(ecore2str(e)); + } + return buf.toString(); + } + + /** + * Returns a eobject from a string. Currently only works for attributes with + * multi=1; + * + * @param str + */ + public T str2ecore(String str) { + String[] fields = str.split(delimRegexp[0],-1); + int j = 0; + T e = sample; + for (EAttribute attr : featureList) { + if (attr == ignoreAttr) { + j++; + continue; + } + if (j >= fields.length) { + if (lenient) { + if (errors != null) + errors.add("Too Fee fields", e.eClass().getName()); + break; + } + throw new RuntimeException("Too Few fields j=" + j + " " + str); + } + EDataType t = attr.getEAttributeType(); + if (attr.getUpperBound() == -1) { + EList<Object> l = new BasicEList<Object>(); + String s = fields[j++]; + String[] values = {}; + // empty string should an empty list instead of a one element list with and empty string + if (s.length()>0) values = s.split(delimRegexp[1],-1); + for (String v : values) { + String vv = fixValue(t, v); + l.add(t.getEPackage().getEFactoryInstance().createFromString(attr.getEAttributeType(), vv)); + } + e.eSet(attr, l); + } else { + String v = fixValue(t, fields[j++]); + e.eSet(attr, t.getEPackage().getEFactoryInstance().createFromString(attr.getEAttributeType(), v)); + } + } + return e; + } + + private String fixValue(EDataType t, String v) { + if (t.getName().equals("EBoolean")) { + if (v.equals("0")) + return "false"; + if (v.equals("1")) + return "true"; + } + return v; + } + + /** + * Read the lines of a text file and convert them to T using str2ecore. + * + * @param fileName + * @param i + * @param eclass + * @return + */ + public EList<T> file2ecores(String fileName) { + BufferedReader reader = FileUtils.filename2reader(fileName, null); + EList<T> res = new BasicEList<T>(); + if (reader == null) + return res; + try { + while (true) { + String line = reader.readLine(); + if (line == null) + break; + res.add((T) EcoreUtil.copy(str2ecore(line))); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } finally { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return res; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EUtils.java new file mode 100644 index 0000000..bb140f8 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EUtils.java @@ -0,0 +1,377 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class EUtils<T extends EObject> { + public static final Logger logger = Logger.getLogger(EUtils.class); + private ResourceSet resourceSet; + private EPackage p; + private boolean useProxy; + private HashMap<String, List<String>> features = new HashMap<String, List<String>>(); + + public EUtils(EPackage p1) { + p = p1; + if (p != null && resourceSet == null) { + resourceSet = new ResourceSetImpl(); + resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl()); + resourceSet.getPackageRegistry().put(p.getNsPrefix(), p.getEFactoryInstance()); + } + } + + public T file2ecore(String fileName) { + return file2ecore(fileName, true); + } + + @SuppressWarnings("unchecked") + public T file2ecore(String fileName, boolean unload) { + File file = new File(fileName); + if (!file.exists()) { + throw new RuntimeException("File does not exists: " + fileName); + } + // URI uri = URI.createFileURI(file.getAbsolutePath()); + URI uri = URI.createURI("file:///" + file.getAbsolutePath().replace("\\", "/")); + Resource resource; + System.err.println("Loading " + uri); + resource = resourceSet.getResource(uri, true); + // throw new RuntimeException("Bad responds"); + EObject e = resource.getContents().get(0); + if (unload) + resource.unload(); + return (T) e; + } + + public void json2ecore(JSONObject o, T e) throws JSONException { + json2ecore2(o, e); + } + + private void json2ecore2(JSONObject o, EObject e) throws JSONException { + if (o == null) + return; + for (EReference feature : e.eClass().getEAllReferences()) { + if (feature.getUpperBound() == -1 || feature.getUpperBound() > 1) { + JSONArray a = o.getJSONArray(feature.getName()); + EList<EObject> l = new BasicEList<EObject>(); + for (int i = 0; i < a.length(); i++) { + EObject e1 = p.getEFactoryInstance().create(feature.eClass()); + json2ecore2((JSONObject) a.get(i), e1); + l.add(e1); + } + e.eSet(feature, l); + } else { + EObject e1 = p.getEFactoryInstance().create(feature.eClass()); + json2ecore2(o.getJSONObject(feature.getName()), e1); + e.eSet(feature, e1); + } + } + for (EAttribute attr : e.eClass().getEAllAttributes()) { + EDataType t = attr.getEAttributeType(); + if (attr.getUpperBound() == -1 || attr.getUpperBound() > 1) { + JSONArray a = o.getJSONArray(attr.getName()); + EList<Object> l = new BasicEList<Object>(); + for (int i = 0; i < a.length(); i++) { + String s = a.getString(i); + Object oo = t.getEPackage().getEFactoryInstance().createFromString(t, s); + l.add(oo); + } + e.eSet(attr, l); + + } else { + String s = o.getString(attr.getName()); + Object oo = t.getEPackage().getEFactoryInstance().createFromString(t, s); + e.eSet(attr, oo); + } + } + } + + @SuppressWarnings("unchecked") + private JSONObject ecore2json(EObject ecore, HashMap<EObject, String> map, String context) throws JSONException { + if (ecore == null) + return null; + JSONObject res = new JSONObject(); + if (useProxy && map.get(ecore) != null) { + res.put("__proxy", map.get(ecore)); + return res; + } + map.put(ecore, context); + if (context.length() > 0) { + context = context + "."; + } + ; + String cfeature = ecore.eContainingFeature() == null ? "none" : ecore.eContainingFeature().getName(); + // res.put("_cfeature", cfeature); + List<String> show = features.get(cfeature); + for (EAttribute attr : ecore.eClass().getEAllAttributes()) { + EDataType t = attr.getEAttributeType(); + if (show != null && show.size() > 0 && !show.contains(attr.getName())) + continue; + if (attr.getUpperBound() == -1 || attr.getUpperBound() > 1) { + JSONArray a = new JSONArray(); + List<Object> l = (List<Object>) ecore.eGet(attr); + for (Object o : l) { + a.put(t.getEPackage().getEFactoryInstance().convertToString(attr.getEAttributeType(), o)); + } + res.put(attr.getName(), a); + } else { + Object o = ecore.eGet(attr); + res.put(attr.getName(), + t.getEPackage().getEFactoryInstance().convertToString(attr.getEAttributeType(), o)); + } + } + for (EReference ref : ecore.eClass().getEAllReferences()) { + if (show != null && show.size() > 0 && !show.contains(ref.getName())) + continue; + if (ref.getUpperBound() == -1 || ref.getUpperBound() > 1) { + JSONArray a = new JSONArray(); + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + int i = 0; + for (EObject o : l) { + JSONObject json = ecore2json(o, map, context + ref.getName() + i); + a.put(json); + json.put("__index", i); + i++; + } + res.put(ref.getName(), a); + } else { + Object ee = ecore.eGet(ref); + res.put(ref.getName(), ecore2json((EObject) ee, map, context + ref.getName())); + } + } + return res; + } + + public JSONObject ecore2json(T ecore) { + try { + return ecore2json(ecore, new HashMap<EObject, String>(), ""); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + public String ecore2jsonString(T ecore, int indentFactor) { + return ecore2json(ecore, new HashMap<EObject, String>(), "").toString(indentFactor); + } + + protected String[] delim = { "%", "@" }; + + public void setDelim(String[] delim) { + this.delim = delim; + } + + String ecore2str(T e, int i) { + EStructuralFeature f = e.eClass().getEStructuralFeature(i); + return e.eGet(f).toString(); + } + + String ecore2str(T e, int[] i) { + StringBuffer res = new StringBuffer(); + for (int j = 0; j < i.length; j++) { + if (j > 0) + res.append(delim[0]); + res.append(ecore2str(e, i[j])); + } + return res.toString(); + } + + String ecore2str(T e, int[][] i) { + throw new RuntimeException("TODO"); + } + + public String ecorelist2str(EList<T> list) { + StringBuffer buf = new StringBuffer(); + boolean first = true; + for (T e : list) { + if (!first) { + buf.append(":"); + } + first = false; + buf.append(e.toString()); + } + return buf.toString(); + } + + /** + * Returns a eobject from a string. Currently only works for attributes with + * multi=1; + * + * @param str + * @param i + * a list of features + * @param eclass + * (The eclass of T is needed) Redundant. How do I fix this? + */ + @SuppressWarnings("unchecked") + public T str2ecore(String str, int[] i, EClass eclass) { + String[] fields = str.split(delim[0]); + T e = (T) p.getEFactoryInstance().create(eclass); + for (int j = 0; j < i.length; j++) { + EAttribute attr = e.eClass().getEAllAttributes().get(i[j]); + EDataType t = attr.getEAttributeType(); + if (attr.getUpperBound() == -1) + throw new RuntimeException("Does not handle this case"); + String v = fixValue(t, fields[j]); + e.eSet(attr, t.getEPackage().getEFactoryInstance().createFromString(attr.getEAttributeType(), v)); + } + return e; + } + + private String fixValue(EDataType t, String v) { + if (t.getName().equals("EBoolean")) { + if (v.equals("0")) + return "false"; + if (v.equals("1")) + return "true"; + } + return v; + } + + /** + * Read the lines of a text file and convert them to T using str2ecore. + * + * @param fileName + * @param i + * @param eclass + * @return + */ + public EList<T> file2ecores(String fileName, int[] i, EClass eclass) { + BufferedReader reader = FileUtils.filename2reader(fileName, null); + EList<T> res = new BasicEList<T>(); + if (reader == null) + return res; + try { + while (true) { + String line = reader.readLine(); + if (line == null) + break; + res.add(str2ecore(line, i, eclass)); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return res; + } + + @SuppressWarnings("unchecked") + public static String attrToString(EObject o, EAttribute attr) { + EDataType t = attr.getEAttributeType(); + Object v = o.eGet(attr); + String vv; + if (attr.getUpperBound() == -1) { + List<String> ss = new ArrayList<String>(); + for (Object vvv : (List<Object>) v) { + ss.add(t.getEPackage().getEFactoryInstance().convertToString(t, vvv)); + } + vv = ss.toString(); + } + else { + vv = t.getEPackage().getEFactoryInstance().convertToString(t, v); + } + return vv; + } + + public static String attrToString(EObject o, String aName) { + EStructuralFeature s = o.eClass().getEStructuralFeature(aName); + if (s instanceof EAttribute) { + return attrToString(o, (EAttribute) s); + } + return null; + } + + public static List<Object> refName2objects(EObject o, String name) { + return refName2objects(o, name.split("\\."),0); + } + + + @SuppressWarnings("unchecked") + private static List<Object> refName2objects(EObject o, String[] names, int i) { + List<Object> l = new ArrayList<Object>(); + if (o == null || i >= names.length) return l; + EStructuralFeature feature = o.eClass().getEStructuralFeature(names[i]); + if (feature == null) return l; + if (i == names.length-1) { + if (feature.isMany()) { + l.addAll((List<Object>) o.eGet(feature)); + } + else { + l.add(o.eGet(feature)); + } + } + else { + EReference ref = (EReference) feature; + if (ref.isMany()) { + EList<EObject> ll = (EList<EObject>) o.eGet(ref); + for (EObject o2 : ll) { + l.addAll(refName2objects(o2, names, i+1)); + } + } + else { + l.addAll(refName2objects((EObject) o.eGet(ref), names, i+1)); + } + } + return l; + } + + public static EOperation name2operation(EClass c, String opName) { + for (EOperation op : c.getEAllOperations()) { + if (op.getName().equals(opName)) return op; + } + logger.warn("Unable to find operation: " + opName + " " + c.getName()); + return null; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EWriter.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EWriter.java new file mode 100644 index 0000000..fa05bc4 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/EWriter.java @@ -0,0 +1,68 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; + +import org.eclipse.emf.ecore.EObject; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class EWriter<T extends EObject> { + private EStringUtil<T> util = null; + private OutputStreamWriter writer; + private String fileName; + + public EWriter(String fileName2, EStringUtil<T> u) { + util = u; + fileName = fileName2; + boolean gzip = fileName.endsWith(".gz"); + writer = FileUtils.filename2writer(fileName2 + ".tmp", gzip); + } + + public void write(T e) { + try { + writer.write(util.ecore2str(e) + "\n"); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + public void close() { + try { + writer.close(); + File f = new File(fileName + ".tmp"); + File dest = new File(fileName); + f.renameTo(dest); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public String getFileName() { + return fileName; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/Ecore2JavaUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/Ecore2JavaUtils.java new file mode 100644 index 0000000..9691ef1 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/Ecore2JavaUtils.java @@ -0,0 +1,123 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.common.util.Enumerator; + + + +public class Ecore2JavaUtils { + String prefix; + String packageName; + + public Ecore2JavaUtils(String packageName, String prefix) { + this.packageName = packageName; + this.prefix = prefix; + } + + public Object ecore2object(EObject e) { + return ecore2object(e, true); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Object ecore2object(EObject e, boolean recursive) { + Class c; + Object o; + try { + c = Class.forName(packageName + "." + prefix + e.eClass().getName()); + Constructor constructor = c.getConstructor(); + o = constructor.newInstance(); + for (EAttribute attr : e.eClass().getEAllAttributes()) { + Field field = c.getField(attr.getName()); + if (attr.isMany()) { + ArrayList a = new ArrayList(); + EList<Object> l = (EList<Object>) e.eGet(attr); + for (Object oo : l) { + a.add(evalue(e,attr,field.getType(),oo)); + } + field.set(o, a); + } else { + field.set(o, evalue(e,attr,field.getType(),e.eGet(attr))); + } + } + if (!recursive) + return o; + for (EReference ref : e.eClass().getEAllReferences()) { + Field field = c.getField(ref.getName()); + if (ref.isMany()) { + ArrayList a = new ArrayList(); + EList<EObject> l = (EList<EObject>) e.eGet(ref); + for (EObject ee : l) { + a.add(ecore2object(ee)); + } + field.set(o, a); + } else { + field.set(o, ecore2object((EObject) e.eGet(ref))); + } + } + return o; + } catch (Exception e1) { + e1.printStackTrace(); + } + return null; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private Object evalue(EObject e, EAttribute attr, Class c, Object oo) { + // TODO handle EEnum case + if (attr.getEType() instanceof EEnum) { +// GuiView v = GuiView.BIRTREPORT; +// XGuiView xv = XGuiView.valueOf(v.getLiteral()); + Enumerator e1 = (Enumerator) oo; + try { + Method m = c.getMethod("valueOf", String.class); + return m.invoke(null,e1.getLiteral()); + } catch (Exception e2) { + e2.printStackTrace(); + } + return null; + } + return oo; + } + + public EObject object2ecore(EClass eClass, Object e) { + // TODO + return null; + } + + public Object doOperation(EObject e, String opName, List<Object> args) { + return null; + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/Ecore2Xmi.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/Ecore2Xmi.java new file mode 100644 index 0000000..c2f0352 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/Ecore2Xmi.java @@ -0,0 +1,48 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.io.IOException; +import java.lang.reflect.Field; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EcorePackage; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class Ecore2Xmi { + + public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, IOException { + // Usage name of Package class file .... + System.out.println(args.toString()); + for (int i = 0; i<args.length ; i += 2) { + System.out.println(args[i]); + System.out.println(args[i+1]); + Class<?> cls = Class.forName(args[i]); + Field f = cls.getDeclaredField("eINSTANCE"); + EPackage p = (EPackage) f.get(null); + FileUtils.ecore2file(EcorePackage.eINSTANCE, p, args[i+1]); + } + System.exit(0); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/MonitoringDynamicMBean.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/MonitoringDynamicMBean.java new file mode 100644 index 0000000..7961f14 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/emf/MonitoringDynamicMBean.java @@ -0,0 +1,117 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.emf; + +import java.util.Iterator; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.InvalidAttributeValueException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanOperationInfo; +import javax.management.ReflectionException; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; + +public class MonitoringDynamicMBean implements DynamicMBean { + private EObject o; + private String name; + + public MonitoringDynamicMBean(EObject o, String name) { + super(); + this.o = o; + this.name = name; + } + + @Override + public Object getAttribute(String arg0) throws AttributeNotFoundException, MBeanException, ReflectionException { + // TODO Auto-generated method stub + return null; + } + + @Override + public AttributeList getAttributes(String[] names) { + AttributeList list = new AttributeList(); + for (String name : names) { + EStructuralFeature f = o.eClass().getEStructuralFeature(name); + if (f == null || !(f instanceof EAttribute)) + continue; + EAttribute attr = (EAttribute) f; + Object value = o.eGet(attr); + if (value == null) + continue; + list.add(new Attribute(name, value.toString())); + } + return list; + } + + @Override + public MBeanInfo getMBeanInfo() { + EList<MBeanAttributeInfo> attrs = new BasicEList<MBeanAttributeInfo>(); + for (EAttribute attr : o.eClass().getEAllAttributes()) { + if (attr.getEType().getName().equals("EBoolean")) { + attrs.add(new MBeanAttributeInfo(attr.getName(), "java.lang.Boolean", attr.getName(), true, true, true)); + } else { + attrs.add(new MBeanAttributeInfo(attr.getName(), "java.lang.String", "NAME " + attr.getName(), true, + true, false)); + } + } + // sample + MBeanOperationInfo[] opers = { new MBeanOperationInfo("reload", "Reload properties from file", null, "void", MBeanOperationInfo.ACTION) }; + // This is need since attrs.toArray() does not work. + MBeanAttributeInfo[] attrs2 = new MBeanAttributeInfo[attrs.size()]; + Iterator<MBeanAttributeInfo> it2 = attrs.iterator(); + for (int i = 0; i < attrs.size(); i++) { + attrs2[i] = it2.next(); + } + MBeanInfo m = new MBeanInfo(this.getClass().getName(), name, attrs2, null, opers, null); + return m; + } + + @Override + public Object invoke(String arg0, Object[] arg1, String[] arg2) throws MBeanException, ReflectionException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setAttribute(Attribute arg0) throws AttributeNotFoundException, InvalidAttributeValueException, + MBeanException, ReflectionException { + // TODO Auto-generated method stub + + } + + @Override + public AttributeList setAttributes(AttributeList arg0) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/logging/LoggingUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/logging/LoggingUtils.java new file mode 100644 index 0000000..d943398 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/logging/LoggingUtils.java @@ -0,0 +1,81 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.logging; + +import java.util.Date; +import java.util.Enumeration; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; + +import org.openecomp.ncomp.utils.maps.HashMapMapMap; + +/** + * Utilities for handling logging. + * + */ +public class LoggingUtils { + /** + * Close all log4j JMS appenders. This disconnect from the JMS in a clean way. + * <p> + * Should only be called just before process exit. + */ + public static void closeJMSAppenders() { + Enumeration<?> e = Logger.getRootLogger().getAllAppenders(); + System.out.println(e); + while (e.hasMoreElements()) { + Object o = e.nextElement(); + System.out.println(o); + if (o instanceof org.apache.log4j.net.JMSAppender) { + org.apache.log4j.net.JMSAppender a = (org.apache.log4j.net.JMSAppender) o; + a.close(); + } + } + } + static private HashMapMapMap<Logger, Level, String, LoggerStat> m = new HashMapMapMap<Logger, Level, String, LoggerStat>(); + + public static void dampingLogger(Logger logger, Level level, String message) { + dampingLogger(logger, level, message, message); + } + public static void dampingLogger(Logger logger, Level level, String category, String message) { + LoggerStat s = m.get(logger, level, category); + if (s == null) { + s = new LoggerStat(); + m.insert(logger, level, category, s); + } + if (s.start.getTime() + 3600*1000 < new Date().getTime() ) { + logger.log(level, category + " in last hour " + s.num + " times"); + s.num = 0; + s.start = new Date(); + } + if (s.num < 5) { + logger.log(level,message); + } + s.num++; + } +} + +class LoggerStat { + Date start = new Date(); + int num = 0; +} + diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/ConnectedMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/ConnectedMap.java new file mode 100644 index 0000000..365b9d9 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/ConnectedMap.java @@ -0,0 +1,64 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ConnectedMap<N> { + static final long serialVersionUID = 1L; + HashMap<N,N> representive = new HashMap<N, N>(); + HashMapList<N,N> rep2list = new HashMapList<N,N>(); + public N add(N node) { + N n = representive.get(node); + if (n == null) { + representive.put(node, node); + rep2list.insert(node, node); + n = node; + } + return n; + } + public void join (N n1, N n2) { +// System.out.println("join: " + n1 + " " + n2); + N r1 = add(n1); + N r2 = add(n2); + if (r1 == r2) return; + if (rep2list.get(r1).size() < rep2list.get(r2).size()) { + N r3 = r1; + r1 = r2; + r2 = r3; + } + List<N> l = rep2list.get(r1); + for (N n : rep2list.get(r2)) { + representive.put(n, r1); + l.add(n); + } + rep2list.remove(r2); + } + public Set<N> reps() { + return rep2list.keySet(); + } + public List<N> values(N n) { + return rep2list.get(add(n)); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/CounterMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/CounterMap.java new file mode 100644 index 0000000..e0ec87e --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/CounterMap.java @@ -0,0 +1,44 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.HashMap; + +public class CounterMap<K> extends HashMap<K,Integer> { + private static final long serialVersionUID = 1L; + + public void increment(K key) { + Integer i = super.get(key); + int j; + if (i == null) { + super.put(key, 0); + j = 0; + } + else j = i; + put(key, j+1); + } + public Integer get(Object key) { + Integer i = super.get(key); + if (i == null) return 0; + return i; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapList.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapList.java new file mode 100644 index 0000000..f4c4e3a --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapList.java @@ -0,0 +1,69 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +import org.apache.log4j.Logger; + +public class HashMapList<K, V> extends HashMap<K, ArrayList<V>> { + private static final long serialVersionUID = 1L; + + public void insert(K key, V value) { + ArrayList<V> l = super.get(key); + if (l == null) { + l = new ArrayList<V>(); + super.put(key, l); + } + if (value != null) + l.add(value); + } + public void addAll(K key, Collection<V> value) { + ArrayList<V> l = super.get(key); + if (l == null) { + l = new ArrayList<V>(); + super.put(key, l); + } + if (value != null) + l.addAll(value); + } + public boolean contains(K k,V v) { + if (!containsKey(k)) return false; + return get(k).contains(v); + } + public List<V> getList(K k) { + if (containsKey(k)) return get(k); + return new ArrayList<V>(); + } + + public void debug(String surfix, Logger logger) { + if (keySet().size() == 0) { + logger.debug(surfix + "EMPTY!!"); + } + for (K k : keySet()) { + logger.debug(surfix + k + " : " + get(k)); + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMap.java new file mode 100644 index 0000000..a29d896 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMap.java @@ -0,0 +1,61 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.HashMap; +import org.apache.log4j.Logger; + +public class HashMapMap<K1,K2,V> extends HashMap<K1,HashMap<K2,V>> { + private static final long serialVersionUID = 1L; + + public void insert(K1 key1, K2 key2, V value) { + HashMap<K2,V> l = super.get(key1); + if (l == null) { + l = new HashMap<K2,V>(); + super.put(key1, l); + } + l.put(key2, value); + } + public boolean contains(K1 key1, K2 key2) { + HashMap<K2,V> l = super.get(key1); + if (l == null) return false; + return l.containsKey(key2); + } + + public void debug(String surfix, Logger logger) { + if (keySet().size() == 0) { + logger.debug(surfix + "EMPTY!!"); + } + for (K1 k : keySet()) { + HashMap<K2,V> l = super.get(k); + for (K2 k2 : l.keySet()) { + logger.debug(surfix + k + " : " + k2 + " : " + l.get(k2)); + } + } + } + public V get(K1 k1, K2 k2) { + HashMap<K2,V> l = super.get(k1); + if (l == null) + return null; + return l.get(k2); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMapList.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMapList.java new file mode 100644 index 0000000..a02e0d7 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMapList.java @@ -0,0 +1,53 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + +public class HashMapMapList<K1,K2,V> extends HashMap<K1,HashMapList<K2, V>> { + private static final long serialVersionUID = 1L; + + public void insert(K1 key1, K2 key2, V value) { + HashMapList<K2, V> l = super.get(key1); + if (l == null) { + l = new HashMapList<K2, V>(); + super.put(key1, l); + } + l.insert(key2,value); + } + public void addAll(K1 key1, K2 key2, Collection<V> value) { + HashMapList<K2, V> l = super.get(key1); + if (l == null) { + l = new HashMapList<K2, V>(); + super.put(key1, l); + } + l.addAll(key2,value); + + } + public List<V> get(K1 key1, K2 key2) { + HashMapList<K2, V> l = super.get(key1); + if (l == null) return null; + return l.get(key2); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMapMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMapMap.java new file mode 100644 index 0000000..09a1d18 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapMapMap.java @@ -0,0 +1,65 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.HashMap; +import org.apache.log4j.Logger; + +public class HashMapMapMap<K1,K2,K3,V> extends HashMap<K1,HashMapMap<K2,K3,V>> { + private static final long serialVersionUID = 1L; + + public void insert(K1 key1, K2 key2, K3 key3, V value) { + HashMapMap<K2,K3,V> l = super.get(key1); + if (l == null) { + l = new HashMapMap<K2,K3,V>(); + super.put(key1, l); + } + l.insert(key2,key3, value); + } + public boolean contains(K1 key1, K2 key2, K3 key3) { + HashMapMap<K2,K3,V> l = super.get(key1); + if (l == null) return false; + return l.contains(key2,key3); + } + + public void debug(String surfix, Logger logger) { + if (keySet().size() == 0) { + logger.debug(surfix + "EMPTY!!"); + } + for (K1 k : keySet()) { + HashMapMap<K2,K3,V> l = super.get(k); + for (K2 k2 : l.keySet()) { + HashMap<K3,V> l2 = l.get(k2); + for (K3 k3 : l2.keySet()) { + logger.debug(surfix + k + " : " + k2 + " : " + k3 + " : " + l2.get(k3)); + } + } + } + } + + public V get(K1 k1, K2 k2, K3 k3) { + HashMapMap<K2,K3,V> l = super.get(k1); + if (l == null) + return null; + return l.get(k2,k3); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapSet.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapSet.java new file mode 100644 index 0000000..cfef554 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashMapSet.java @@ -0,0 +1,53 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.HashMap; +import java.util.HashSet; + +import org.apache.log4j.Logger; + +public class HashMapSet<K, V> extends HashMap<K,HashSet<V>> { + private static final long serialVersionUID = 1L; + + public void insert(K key, V value) { + HashSet<V> l = super.get(key); + if (l == null) { + l = new HashSet<V>(); + super.put(key, l); + } + l.add(value); + } + public boolean contains(K key, V v) { + HashSet<V> l = super.get(key); + if (l == null) return false; + return l.contains(v); + } + public void debug(String surfix, Logger logger) { + if (keySet().size() == 0) { + logger.debug(surfix + "EMPTY!!"); + } + for (K k : keySet()) { + logger.debug(surfix + k + " : " + get(k)); + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashTDoubleMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashTDoubleMap.java new file mode 100644 index 0000000..91b2259 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashTDoubleMap.java @@ -0,0 +1,59 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + +public class HashTDoubleMap { + public static <T> HashMap<T, Double> topN(final HashMap<T, Double> map, int n) { + HashMap<T, Double> res = new HashMap<T, Double>(); + List<T> l = new ArrayList<T>(map.keySet()); + Collections.sort(l, new Comparator<T>() { + @Override + public int compare(T arg0, T arg1) { + Double v1 = map.get(arg0); + Double v2 = map.get(arg1); + return v1.compareTo(v2); + } + }); + for (T key : l) { + res.put(key, map.get(key)); + if (res.size() >= n) + break; + } + return res; + } + public static <T> void incr(final HashMap<T, Double> map, T i, double n) { + Double ii = map.get(i); + if (ii == null) { + ii = new Double(0); + } + map.put(i, ii + n); + } + public static <T> void incr(final HashMap<T, Double> map, T i) { + incr(map,i,1); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashTIntegerMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashTIntegerMap.java new file mode 100644 index 0000000..eee0e97 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/HashTIntegerMap.java @@ -0,0 +1,59 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; + +public class HashTIntegerMap { + public static <T> HashMap<T, Integer> topN(final HashMap<T, Integer> map, int n) { + HashMap<T, Integer> res = new HashMap<T, Integer>(); + List<T> l = new ArrayList<T>(map.keySet()); + Collections.sort(l, new Comparator<T>() { + @Override + public int compare(T arg0, T arg1) { + int v1 = map.get(arg0); + int v2 = map.get(arg1); + return v2-v1; + } + }); + for (T key : l) { + res.put(key, map.get(key)); + if (res.size() >= n) + break; + } + return res; + } + public static <T> void incr(final HashMap<T, Integer> map, T i, int n) { + Integer ii = map.get(i); + if (ii == null) { + ii = new Integer(0); + } + map.put(i, ii + n); + } + public static <T> void incr(final HashMap<T, Integer> map, T i) { + incr(map,i,1); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/InetPrefix.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/InetPrefix.java new file mode 100644 index 0000000..ce1866f --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/InetPrefix.java @@ -0,0 +1,88 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.net.InetAddress; + +import org.openecomp.ncomp.webservice.utils.IpUtils; + +public class InetPrefix { + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((ip == null) ? 0 : ip.hashCode()); + result = prime * result + maskLength; + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + InetPrefix other = (InetPrefix) obj; + if (ip == null) { + if (other.ip != null) + return false; + } else if (!ip.equals(other.ip)) + return false; + if (maskLength != other.maskLength) + return false; + return true; + } + public InetPrefix(InetAddress ip, int maskLength) { + this.ip = IpUtils.mask(ip, maskLength); + this.maskLength = maskLength; + } + public InetPrefix(String s) { + String a[] = s.split("/"); + if (a.length == 2 && IpUtils.isIp(a[0])) { + this.maskLength = Integer.parseInt(a[1]); + this.ip = IpUtils.mask(IpUtils.toInetAddress(a[0]), maskLength); + return; + } + throw new RuntimeException("bad prefix" + s); + } + public InetAddress getIp() { + return ip; + } + protected void setIp(InetAddress ip) { + this.ip = ip; + } + public int getMaskLength() { + return maskLength; + } + protected void setMaskLength(int maskLength) { + this.maskLength = maskLength; + } + private InetAddress ip; + private int maskLength; + @Override + public String toString() { + return ip.getHostAddress() + "/" + maskLength; + } + + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/IntHashMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/IntHashMap.java new file mode 100644 index 0000000..bbc1c28 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/IntHashMap.java @@ -0,0 +1,147 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +// Similar to HashMap<Integer,V>, but without Integer overhead, +// doesn't support remove, and other limitations +public class IntHashMap<V> { + private int size; + private int capacity; + private int[] keys; + private V[] vals; + private V special_val; + private final static double full_load_factor = 0.75; + private final static int initial_capacity = 16; + private final static int special_key = 0; + + public IntHashMap() { + this(initial_capacity); + } + public IntHashMap(int initial_capacity) { + capacity = initial_capacity; + size = 0; + keys = null; + vals = null; + special_val = null; + } + + private long getHash (int key) { + return IntegerHasher.hashT(key); + } + + private int getBin (long hash) { + return (int) (hash & (keys.length-1)); + } + + private int findBin (int key) { + int bin = getBin(getHash(key)); + + while (keys[bin] != special_key && keys[bin] != key) { + bin = (bin + 1) & (keys.length-1); + } + return bin; + } + + private int findEmptyBin (int key) { + int bin = getBin(getHash(key)); +// int bin = (int) (IntegerHasher.hashT(key) & (keys.length-1)); + + while (keys[bin] != special_key) { + bin = (bin + 1) & (keys.length-1); + } + return bin; + } + + @SuppressWarnings("unchecked") + public void grow () { + if (size != 0) { + capacity = size * 2; + } + int[] oldkeys = keys; + V[] oldvals = vals; + int newsz = (keys == null) ? 32 : keys.length*2; + while (newsz * full_load_factor < capacity) newsz *= 2; + capacity = (int) (newsz * full_load_factor); + keys = new int[newsz]; + vals = (V[]) new Object[newsz]; + if (oldkeys != null) { + for (int i=0; i<oldkeys.length; i++) { + if (oldkeys[i] != special_key) { + int b = findEmptyBin (oldkeys[i]); + keys[b] = oldkeys[i]; + vals[b] = oldvals[i]; + } + } + } + } + + public V put(int key, V val) { + if (key == special_key) { + V oldval = special_val; + if (oldval == null) size++; + special_val = val; + return oldval; + } + + if (keys == null) { + grow(); + } + int bin = findBin(key); + if (keys[bin] == special_key) { + size++; + keys[bin] = key; + vals[bin] = val; + if (size >= capacity) { + grow(); + } + return null; + } + V oldval = vals[bin]; + vals[bin] = val; + return oldval; + } + + public V get (int key) { + if (key == special_key) return special_val; + if (keys == null) return null; + int bin = findBin(key); + if (keys[bin] == special_key) return null; + return vals[bin]; + } + + public int size () { + return size; + } + + public int[] getKeys () { + int[] ret = new int[size]; + int cnt = 0; + for (int i=0; i<keys.length; i++) { + if (keys[i] == special_key) continue; + if (cnt >= ret.length){ + throw new RuntimeException("Bad count problem, cnt " + cnt + " size " + size); + } + ret[cnt++] = keys[i]; + } + return ret; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/IntegerHasher.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/IntegerHasher.java new file mode 100644 index 0000000..baef668 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/IntegerHasher.java @@ -0,0 +1,1594 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +public class IntegerHasher { + //Random numbers from random.org based on atmospheric noise. + private static final int[] hashInt1 = new int [] { + 0x5b76523f, 0x0f46057e, 0xe51e1dc7, 0x795cd6dc, + 0x6560d754, 0x43fe97ce, 0x5fb8bbde, 0x3214c211, + 0xf4bdd9f4, 0xcbad5a23, 0x5db3767a, 0x252b219b, + 0xbd28a7b9, 0x0d39ee9b, 0x410c22ea, 0x9624e6c4, + 0xe1c72a00, 0x1afd9e33, 0xd187e6c3, 0x178109c9, + 0x5cf83711, 0x29cab454, 0xf52ae410, 0xefe3f2b3, + 0x229fcdb8, 0x5420ce79, 0xb4f96393, 0x0d926962, + 0x7b5df492, 0x12f71767, 0xa29c21c5, 0x2444a9e7, + 0x08ed6846, 0x0048ccb0, 0x551fff4e, 0xf0677d2b, + 0xbd554dbe, 0xb4f8d5db, 0x81d08df7, 0x5b59cd52, + 0x0141ffe4, 0x35f2b994, 0x41bbce94, 0x66240e36, + 0x82ef9967, 0x0beb2406, 0x6fa05fa8, 0xd2b15cbc, + 0xb12172cf, 0xb9bda30e, 0x87d9c48c, 0xa80551b7, + 0xfdad93c7, 0x15ebfc21, 0x50436502, 0x966687b3, + 0xedd261a5, 0x5f70ccea, 0x6c05ab83, 0xfbd983f1, + 0x2d2cbbd1, 0xa7571eea, 0x82068da1, 0x03739d09, + 0x86ae139e, 0xe667ac29, 0xe27a06e1, 0x5a1f401b, + 0xc68449d3, 0x96a8b5c1, 0x55b05fbb, 0x619a0e5d, + 0x140dd456, 0xfdabe62d, 0x3ef22e99, 0x82162bdf, + 0x856acd46, 0xc3b51bff, 0xa9a93475, 0xc5f2de11, + 0x336c57dc, 0xdaa164a5, 0xafd07783, 0xb97a7d53, + 0x20e41676, 0x238ee3f6, 0xe6c9a5ae, 0x1b178823, + 0xa870af9f, 0x2a1f6878, 0x2c0a76df, 0x96e16873, + 0x77d779ec, 0xa995511b, 0xc75e1c20, 0x5e506d0d, + 0xf67ecfd8, 0x7d4da617, 0x80bd60a0, 0xd7135da1, + 0xdb2bf1da, 0xb52cebd1, 0x0237860c, 0x23dda94c, + 0x26577b39, 0x5a81d683, 0xe87fe5a7, 0xe62ff9de, + 0x8100d1b3, 0xe1f4b996, 0xd595aa7e, 0x8d0af0c5, + 0x6e8005ac, 0x5845bd01, 0xd386e59d, 0x356b7753, + 0x6d78a19a, 0x8c83ff0a, 0x16046aa4, 0x5bb39641, + 0x9cb4ee22, 0x935ce7dd, 0xc55b25aa, 0x4a548acc, + 0x111508ab, 0x7e073207, 0x8944cbce, 0x2987c88c, + 0x27158c2b, 0xed93adbd, 0x8bf0fc02, 0xa456fc9a, + 0xe2c6c2c2, 0x37ca493f, 0x8efcb3f0, 0x2f4f54d7, + 0xdb7eb7de, 0x704f3c95, 0xaa357481, 0xaa427c85, + 0x4d72b3ad, 0xa1648206, 0x41dc5182, 0xe3a08d51, + 0xc29e74c0, 0xa2da7e71, 0x8b8d61b6, 0x878e08b2, + 0x5de59032, 0xf7bbc408, 0xff674228, 0x14a99b1d, + 0x705ea3eb, 0xa78ab612, 0x9047998d, 0x0b35509a, + 0xca398e81, 0xdc56c93c, 0x287252fb, 0x9a2c9a54, + 0x986f6c29, 0x6c8e8d7a, 0xb378364a, 0xa79c9254, + 0x91d066a6, 0x96cf483d, 0xaf3f965f, 0xf5e586ea, + 0xebc6300b, 0x35faac79, 0x00f53e9c, 0x02e98588, + 0x814187ce, 0x1c0bca2c, 0xb597304d, 0x2b468d5a, + 0x2fabea90, 0x446edfc5, 0x6970fb31, 0x74fcd137, + 0x4d0613c0, 0xd5748a99, 0xa85326bf, 0x46256873, + 0x4b6c0b74, 0x4e1f827d, 0xa994def9, 0x1e2dcef7, + 0x0496e23e, 0x3f56235d, 0xbf49ddf8, 0xcaf042ec, + 0xd42d3d49, 0xd5f9bc16, 0x02e389a6, 0x1c6f73ba, + 0x686f8afe, 0xd0a37391, 0x0fce690a, 0x3d6ba998, + 0xe26c34b5, 0xd9ada7a6, 0x17dad244, 0xc25243c7, + 0xc7d52b60, 0x5ce18770, 0xd9ab3dae, 0x96f47ab2, + 0x64bad783, 0x91d8686d, 0x649c4825, 0x6001dbb6, + 0x79e69d19, 0xd042095c, 0x4d54b150, 0xc4eb2070, + 0xd2aa84ca, 0x7b6472b8, 0xfed120e9, 0xc89c7684, + 0xc65588e9, 0xed3ad3b9, 0x805a7992, 0xe7f944b5, + 0x933e8675, 0x68fc38fd, 0x9836ae5b, 0xfcd2e40e, + 0x7ea44f90, 0xad678ad3, 0x0a4076dc, 0xf1d3ff79, + 0x1b5ac30a, 0x4aa3a39f, 0x0fe9d41a, 0xc0726751, + 0x6c941442, 0xb3e0b471, 0x24f3918a, 0x86ac6153, + 0x26fa9d31, 0xed4763bc, 0xbbb71937, 0x276de2f5, + 0x98839021, 0x2cc2105a, 0xa15af9d3, 0x4ff3735f, + 0x7065b8c5, 0xfbbe7e9b, 0x1264dd28, 0xe902a0ec, + 0x01bcdf35, 0x849c01d9, 0x4b6cf0a4, 0x10359389, + }; + private static final int[] hashInt2 = new int[] { + 0xe2963e32, 0x25c418cb, 0x12b14d79, 0x824d6afa, + 0x926728fb, 0xd8ab2e6c, 0x2f776882, 0x537d7a74, + 0x509c2a7a, 0x6d7529d9, 0xda6351f2, 0x1cc9990c, + 0x216a41bf, 0x99faa5b8, 0x71c108ff, 0xac80cc33, + 0x1d4d64b8, 0xf905a66c, 0x912d58f0, 0x4b69de56, + 0x07ee269d, 0xe2c46497, 0x9d7a589d, 0xe1e7eda6, + 0x395588af, 0x7e192977, 0xa2d623ec, 0x3eda88d6, + 0xf0cca5d4, 0xc50da528, 0xb65c7108, 0x28465a53, + 0x06d355d7, 0x19dff346, 0xf6b10c71, 0x2799488e, + 0xf60f084f, 0x1239d5da, 0x84c87c04, 0x8a8f8e41, + 0x6827a4bf, 0x00bdcb3a, 0x909ed01b, 0xcd2c85ee, + 0x9e36136d, 0xf56b6bf1, 0xb1f3c9ba, 0xf0198095, + 0x314c0a7c, 0x5c8fb3ea, 0xc4109133, 0x1b7e281f, + 0xa7febd65, 0x0e585930, 0xb7c4bffe, 0x434ead73, + 0x85169334, 0xbb36084c, 0x37b31b88, 0xc923b35c, + 0x8be6a906, 0x6466427f, 0xe1e694fe, 0xb0871ffe, + 0x88854d80, 0xbb8fd24d, 0x20bab388, 0x78c07159, + 0x22f99750, 0xb770cebc, 0x03eaef9f, 0x5aca5248, + 0x6636f7d2, 0x3fb66ee4, 0xc0e8bcf6, 0xf86f1acf, + 0x2a659e9e, 0xa3c7d415, 0x82a00b25, 0xc5f08c59, + 0x3a4062b5, 0x86233e64, 0xb0a0eaed, 0xaed7378f, + 0x27ad3fe8, 0xd788fbf1, 0x30784305, 0x06d86e87, + 0x0a3a1f2c, 0x93cfddf9, 0x8f0a6d19, 0x6ff76952, + 0x6ca7285e, 0xfad449c1, 0x63d470f1, 0x4044ef8d, + 0xd2489ff0, 0x6f71392a, 0x0f8764d0, 0x4dd3fc5d, + 0x1ffa6ce2, 0x407d7c74, 0xb6d252d4, 0x8ca57a3e, + 0x63dcc740, 0x80595c17, 0xe6b0d470, 0xa3cdce43, + 0xd6ed2569, 0x63241fe4, 0xf1553976, 0x4413b911, + 0x92bc91a2, 0x5c2bcb14, 0x2304a60b, 0x8c77edef, + 0x19408bbd, 0x1d8a92e0, 0x1944defa, 0x74f2e5a3, + 0x9cb128aa, 0xaab45b03, 0xbedfe6f7, 0x8c5d6f88, + 0xab237865, 0xafa2a3cd, 0xfd846843, 0xd1af81d0, + 0xfd20f3f1, 0x4264ea95, 0xb7b0fca5, 0xfd65fefb, + 0xd32d668c, 0x1815e875, 0x970dde0a, 0x6859e6f6, + 0xa94396e7, 0x12480333, 0xccd54e6b, 0xcd153763, + 0x05dac108, 0xa9062363, 0x0860df10, 0x9ca43875, + 0x5cca6dca, 0xeb9481a1, 0x8d6d1b44, 0x7e356048, + 0x3c847789, 0x3d3b0b7e, 0x04ec728b, 0x81a07fcb, + 0x612c681d, 0x92c5558c, 0x489f692a, 0x6d6337f5, + 0x2c0ad993, 0x450a314f, 0xa1334949, 0xc0529674, + 0xc7b9e550, 0xfbda013f, 0x93bbbdd7, 0xf15d9e65, + 0x66e20a2c, 0xfa25b480, 0x18791426, 0x1712da76, + 0x7f578115, 0x8d342d4a, 0xf65c6194, 0xe4ea3dd5, + 0x1c8c0b95, 0x220c5582, 0x3115c4f2, 0xba3536e7, + 0xa004ac37, 0x75af607f, 0xfd05aa5f, 0x3cfca7eb, + 0x6cc1aa02, 0x81d4afd5, 0x86e520b7, 0xedbd80d9, + 0xe6f62a06, 0x1d64c482, 0x0a285f1b, 0xf2858c33, + 0x5b19129a, 0xc35d75d0, 0xd3aad385, 0xb0325dc3, + 0xd012e3d2, 0x70933968, 0x27c4be20, 0x0a2e1c98, + 0x593c82db, 0xfb9e0c98, 0xfc7abfb7, 0x6f598044, + 0xcb7d4ed6, 0x24b136d0, 0x7f6f8d72, 0x4db28c0b, + 0x0e1ab87e, 0x223d38b5, 0x9a69d76c, 0x05147572, + 0x9b5aa7d3, 0x3f725000, 0x7943acb3, 0x0f976cd4, + 0xb4dbf321, 0xee7c0155, 0xa6d1d372, 0xdef690d1, + 0x8bcf1b8b, 0xe7caf18d, 0x77eac1a2, 0x156e5778, + 0x7dc05f94, 0x2375128a, 0x06ce025a, 0x5a1410aa, + 0xd92c7e1a, 0xbf63a63f, 0xef7d0885, 0xc7fcb5c4, + 0xa52ea477, 0xcb327fab, 0x7851b56e, 0xe9b7c2a8, + 0x38b9ba75, 0xa3019502, 0xb79478d6, 0x00bdd267, + 0x412c2e70, 0xf35f990c, 0xc39e9533, 0x83f569e5, + 0x0aa196b5, 0xc7b4d1a8, 0x563a7c2c, 0x38d3a2a8, + 0xaed42541, 0x319eb596, 0x94c0f8c5, 0xeef6a110, + 0x879d61c7, 0xb91eb5f5, 0xdaac9c03, 0x37c79064, + 0xb670a834, 0xd8ee629a, 0xc4bb62d7, 0x48f7ad3e, + }; + private static final int[] hashInt3 = new int[] { + 0xdc29717c, 0x176df2be, 0x663e45ea, 0x207bcecf, + 0xb46ff325, 0x77245234, 0x5cd540fb, 0x0e638cfd, + 0x8aa1bdc8, 0x6d011a76, 0xaffec018, 0xe91fb051, + 0x536c26f7, 0x08379769, 0xeaf791ac, 0xba802df7, + 0x6d7bf937, 0xbc1e4d96, 0xbbfc90dc, 0x1b3a6399, + 0x2c45efd7, 0xefc36b4a, 0xcd079e6a, 0xe613dc0e, + 0xca26d81b, 0x3adca34f, 0x46ff113f, 0xe094f4a8, + 0x9ccf662e, 0x4089cb15, 0xd3d724de, 0x6ee5155b, + 0x7772bea1, 0x558d6a66, 0x231ea576, 0x7fbdd982, + 0xa776e21f, 0xc9de14c9, 0x38b8bfa3, 0xbf4b0303, + 0x76c5789d, 0x3febda0f, 0x7e286aab, 0xb3fab440, + 0xf9cd8a24, 0x8e43e5d0, 0xd61c929a, 0x09b98aac, + 0xd1f844fb, 0xa207e51b, 0x0fa2be7e, 0x40ae9e32, + 0x068081b1, 0xd9bf5a67, 0x1c8c2f90, 0x6598bef2, + 0x0b3fc123, 0x4253abfe, 0x10123bfc, 0xac51b96d, + 0x4f294f18, 0xabdfa633, 0x544b71cf, 0x5eadc5b1, + 0x406e7f73, 0x38933ab0, 0x29879d37, 0xc0f8fde2, + 0x43ef9a51, 0x7a78ebed, 0x9dee7fb6, 0xd66ecfe1, + 0xc052e1c8, 0x15ee4879, 0x6e751cf3, 0xb8a823c2, + 0x75d80e2d, 0xab587670, 0x3aef4bc7, 0x1cdcf825, + 0xc1885255, 0xf7a539f7, 0x0f07fc8d, 0x083e591c, + 0xaba46ff5, 0x1eea1411, 0x7154027a, 0x91acac46, + 0x9dd9e176, 0x35ac22cc, 0xcaf65a49, 0x05637d9f, + 0x02ee5b7d, 0xfd297a56, 0x1d141b3d, 0x7ff357c7, + 0x07bf52a5, 0xfa823415, 0x936c6e25, 0xd420963b, + 0xb2452302, 0x9420b806, 0x9133cd3d, 0x98f99e67, + 0x450c391f, 0xff9bc142, 0x1759c144, 0x1e2891d6, + 0x7e4ee4b9, 0x337d2d8c, 0x0964814e, 0x695e4cdc, + 0xbe05f123, 0xbfd66f80, 0xdadbd4a9, 0x0f93eab9, + 0x89ef1026, 0xc4ea9855, 0xa6128cb9, 0x49525266, + 0x389ddb19, 0xe086862c, 0xb7507759, 0xc50e9be7, + 0x80a0710c, 0xff268e7c, 0x1327353e, 0xedf58018, + 0x1f907434, 0x40045e2a, 0x70580d3f, 0x9f5ee603, + 0x984876d4, 0xbabd051f, 0x7a25e2b0, 0x8ca524fc, + 0xc6f784df, 0x01587b48, 0x5b8fc6e1, 0x697ebc8c, + 0x205f0229, 0x72dd67a1, 0xae238d74, 0x0326dd55, + 0xb8366a74, 0x3b9c1082, 0x48dda93c, 0xdc780676, + 0x50fe2976, 0x291f07f0, 0x1fa89afd, 0xd49a91ec, + 0x93f4db5c, 0x977806e6, 0x237c8735, 0xef83837d, + 0x1fa32457, 0xacb5e8a1, 0x124bc782, 0x605555b3, + 0x638e7a0e, 0x1c2a19a6, 0xe2a1811b, 0x29eb20aa, + 0xb359b456, 0x01535a73, 0x2e4eb1f9, 0x86f03c94, + 0x93cc70b6, 0xf15f6fd8, 0xa1cf70cd, 0x3bd0b81a, + 0x6e33634a, 0x5f5bdb60, 0xcd02febc, 0xadc96245, + 0x839b2f2c, 0x52977d68, 0xceb8bfc8, 0x4bda7994, + 0x2e8c1b5d, 0x844b7c6e, 0x06955992, 0xc137d9ef, + 0x296ff5df, 0x745c8327, 0x88edc4c1, 0xcdcff099, + 0x4ad2e327, 0x4b7417ae, 0x78f01d7c, 0xecf03844, + 0xae4d4c8d, 0xbf877a02, 0xba91b747, 0x0c79a3de, + 0x2d04ec9d, 0x0c1fb9ba, 0xc999398f, 0xf9d34fbd, + 0xffcdb8fc, 0xe5ebddab, 0x589da682, 0xd08da50f, + 0xd1ee4caf, 0xd080e748, 0xef5e7580, 0x7494074b, + 0xa5390267, 0xf7c7fe47, 0x900f2016, 0xb439f9a2, + 0x30a6112a, 0x1d611e6c, 0xde0f88fa, 0xfa8c917d, + 0xd2bcbfb2, 0xc9b38014, 0xdb85fe7f, 0xc6051784, + 0x6253ff25, 0x1127c75e, 0x05ac1cf7, 0x978a5acc, + 0x3f5562ca, 0x3b96a4f1, 0x43c19534, 0x7baa6369, + 0xd39054be, 0x5c96e49c, 0x6b192c2b, 0x1b7f8214, + 0xd6de9655, 0x6f8f4157, 0x0f6bb91f, 0x8dd1e0ae, + 0xea0539af, 0x40ea392f, 0x9daf88e6, 0x924a7281, + 0xb1d00b77, 0x0536f269, 0x3b4930e6, 0x71e478c2, + 0x6e50cde6, 0x15f20b57, 0x62a713e8, 0xb4468dac, + 0x133ebb03, 0x10164a0e, 0x737f4ec9, 0x958ce0c9, + 0xe6a9da43, 0x34409b8c, 0x3f112ee3, 0x390d7512, + }; + private static final int[] hashInt4 = new int[] { + 0xdc29717c, 0x176df2be, 0x663e45ea, 0x207bcecf, + 0xb46ff325, 0x77245234, 0x5cd540fb, 0x0e638cfd, + 0x8aa1bdc8, 0x6d011a76, 0xaffec018, 0xe91fb051, + 0x536c26f7, 0x08379769, 0xeaf791ac, 0xba802df7, + 0x6d7bf937, 0xbc1e4d96, 0xbbfc90dc, 0x1b3a6399, + 0x2c45efd7, 0xefc36b4a, 0xcd079e6a, 0xe613dc0e, + 0xca26d81b, 0x3adca34f, 0x46ff113f, 0xe094f4a8, + 0x9ccf662e, 0x4089cb15, 0xd3d724de, 0x6ee5155b, + 0x7772bea1, 0x558d6a66, 0x231ea576, 0x7fbdd982, + 0xa776e21f, 0xc9de14c9, 0x38b8bfa3, 0xbf4b0303, + 0x76c5789d, 0x3febda0f, 0x7e286aab, 0xb3fab440, + 0xf9cd8a24, 0x8e43e5d0, 0xd61c929a, 0x09b98aac, + 0xd1f844fb, 0xa207e51b, 0x0fa2be7e, 0x40ae9e32, + 0x068081b1, 0xd9bf5a67, 0x1c8c2f90, 0x6598bef2, + 0x0b3fc123, 0x4253abfe, 0x10123bfc, 0xac51b96d, + 0x4f294f18, 0xabdfa633, 0x544b71cf, 0x5eadc5b1, + 0x406e7f73, 0x38933ab0, 0x29879d37, 0xc0f8fde2, + 0x43ef9a51, 0x7a78ebed, 0x9dee7fb6, 0xd66ecfe1, + 0xc052e1c8, 0x15ee4879, 0x6e751cf3, 0xb8a823c2, + 0x75d80e2d, 0xab587670, 0x3aef4bc7, 0x1cdcf825, + 0xc1885255, 0xf7a539f7, 0x0f07fc8d, 0x083e591c, + 0xaba46ff5, 0x1eea1411, 0x7154027a, 0x91acac46, + 0x9dd9e176, 0x35ac22cc, 0xcaf65a49, 0x05637d9f, + 0x02ee5b7d, 0xfd297a56, 0x1d141b3d, 0x7ff357c7, + 0x07bf52a5, 0xfa823415, 0x936c6e25, 0xd420963b, + 0xb2452302, 0x9420b806, 0x9133cd3d, 0x98f99e67, + 0x450c391f, 0xff9bc142, 0x1759c144, 0x1e2891d6, + 0x7e4ee4b9, 0x337d2d8c, 0x0964814e, 0x695e4cdc, + 0xbe05f123, 0xbfd66f80, 0xdadbd4a9, 0x0f93eab9, + 0x89ef1026, 0xc4ea9855, 0xa6128cb9, 0x49525266, + 0x389ddb19, 0xe086862c, 0xb7507759, 0xc50e9be7, + 0x80a0710c, 0xff268e7c, 0x1327353e, 0xedf58018, + 0x1f907434, 0x40045e2a, 0x70580d3f, 0x9f5ee603, + 0x984876d4, 0xbabd051f, 0x7a25e2b0, 0x8ca524fc, + 0xc6f784df, 0x01587b48, 0x5b8fc6e1, 0x697ebc8c, + 0x205f0229, 0x72dd67a1, 0xae238d74, 0x0326dd55, + 0xb8366a74, 0x3b9c1082, 0x48dda93c, 0xdc780676, + 0x50fe2976, 0x291f07f0, 0x1fa89afd, 0xd49a91ec, + 0x93f4db5c, 0x977806e6, 0x237c8735, 0xef83837d, + 0x1fa32457, 0xacb5e8a1, 0x124bc782, 0x605555b3, + 0x638e7a0e, 0x1c2a19a6, 0xe2a1811b, 0x29eb20aa, + 0xb359b456, 0x01535a73, 0x2e4eb1f9, 0x86f03c94, + 0x93cc70b6, 0xf15f6fd8, 0xa1cf70cd, 0x3bd0b81a, + 0x6e33634a, 0x5f5bdb60, 0xcd02febc, 0xadc96245, + 0x839b2f2c, 0x52977d68, 0xceb8bfc8, 0x4bda7994, + 0x2e8c1b5d, 0x844b7c6e, 0x06955992, 0xc137d9ef, + 0x296ff5df, 0x745c8327, 0x88edc4c1, 0xcdcff099, + 0x4ad2e327, 0x4b7417ae, 0x78f01d7c, 0xecf03844, + 0xae4d4c8d, 0xbf877a02, 0xba91b747, 0x0c79a3de, + 0x2d04ec9d, 0x0c1fb9ba, 0xc999398f, 0xf9d34fbd, + 0xffcdb8fc, 0xe5ebddab, 0x589da682, 0xd08da50f, + 0xd1ee4caf, 0xd080e748, 0xef5e7580, 0x7494074b, + 0xa5390267, 0xf7c7fe47, 0x900f2016, 0xb439f9a2, + 0x30a6112a, 0x1d611e6c, 0xde0f88fa, 0xfa8c917d, + 0xd2bcbfb2, 0xc9b38014, 0xdb85fe7f, 0xc6051784, + 0x6253ff25, 0x1127c75e, 0x05ac1cf7, 0x978a5acc, + 0x3f5562ca, 0x3b96a4f1, 0x43c19534, 0x7baa6369, + 0xd39054be, 0x5c96e49c, 0x6b192c2b, 0x1b7f8214, + 0xd6de9655, 0x6f8f4157, 0x0f6bb91f, 0x8dd1e0ae, + 0xea0539af, 0x40ea392f, 0x9daf88e6, 0x924a7281, + 0xb1d00b77, 0x0536f269, 0x3b4930e6, 0x71e478c2, + 0x6e50cde6, 0x15f20b57, 0x62a713e8, 0xb4468dac, + 0x133ebb03, 0x10164a0e, 0x737f4ec9, 0x958ce0c9, + 0xe6a9da43, 0x34409b8c, 0x3f112ee3, 0x390d7512, + 0xbbfc7f1f, 0x6f7f4177, 0x9f364412, 0x99446e8c, + 0xa09d6271, 0x6a0b898e, 0xfba38a87, 0x518bdc0c, + 0xbb6a0ccb, 0xd4180225, 0x8087261f, 0x0f9f02b4, + 0x17e7a0e7, 0xa483a784, 0x8ffb90f7, 0x30b1926f, + 0x3a99a2bf, 0x6ce3883e, 0x17569cf1, 0x29edc380, + 0x39de644a, 0x5f3c6021, 0xa1cf0381, 0x1449a778, + 0x8adf1841, 0x8bcc0ce6, 0x32ac4e68, 0x85dc0c5c, + 0xa9a8387f, 0x7bcc8346, 0x6a2fd134, 0x8fe5afd6, + 0x5a453197, 0x63215d65, 0x2b472d3d, 0xb4ee6010, + 0xe0ea2bcd, 0xa4004974, 0x917a9ba0, 0x8b4bbbe0, + 0xbdef2223, 0x1b3d1c7b, 0x99ad09e7, 0x8c58dc11, + 0x0e786c0a, 0x6d626b1f, 0x9e425cf1, 0xe084c4e0, + 0x73e1b36b, 0x2cea09ce, 0xee0f4ecf, 0xcc5d9e17, + 0x4f7f96ef, 0xa6f3d6aa, 0xe1b31542, 0x69f161c1, + 0xa5aede01, 0x47475ab3, 0x0cb9a679, 0x715a5ff2, + 0x63bd0c12, 0xac13d310, 0x4da62908, 0xaba8fa5c, + 0xfc156bd1, 0x25b71cf0, 0x22fbf1c7, 0x36331bbd, + 0x29e770dd, 0x5538035e, 0x0595a383, 0xb620aec7, + 0x9dd41884, 0x946a836a, 0x678519a5, 0x38ce1394, + 0x9e2ba8d8, 0x8fffe54b, 0x292373f9, 0x7a0c345c, + 0x84d2b45c, 0xbf70dfef, 0x943617b3, 0xb49ad5cc, + 0xdf2d60ea, 0xf53862cf, 0x7cde290a, 0x887b4758, + 0xa66725bd, 0xb4a21b6a, 0xa9a1ca98, 0xda213586, + 0x80cbc393, 0x2fcaa19e, 0xcb099548, 0xf80d62cd, + 0xa030e986, 0x3c1720db, 0x87374cbd, 0xefbc5ed4, + 0x43d72258, 0xee2daf0e, 0xce8f8a98, 0x82ffc32e, + 0x1b84df12, 0xeef07355, 0xe0305495, 0x5ef389d0, + 0xa5e26880, 0x3e7f140a, 0x559802e9, 0x0d6dc750, + 0x6ba3e521, 0x71986887, 0x317f6555, 0x4e3344e4, + 0x81291385, 0xe2c2e221, 0x63cc077c, 0xfcba77a8, + 0xe1a69f35, 0xb12346e6, 0x28dfeb67, 0xe61abced, + 0x7d3cc36d, 0x4d8bfee3, 0xc462ba30, 0x57e5ecdd, + 0xee8b6917, 0x96e7d908, 0x304731e1, 0x3a6db848, + 0x798b8860, 0x8089203e, 0x3a34c3d9, 0xd7a505b9, + 0x36575c83, 0x76b297d4, 0x4cb1aaec, 0xf40679da, + 0x60ae7ab7, 0x1c141f12, 0x4c0f41b1, 0x0523535b, + 0x86302b26, 0x845bbcfe, 0xb24f69eb, 0x9b72b7a5, + 0xfed4b4aa, 0xc50a4192, 0x951156ac, 0x8b4fd213, + 0x6644c53d, 0x4e18c1be, 0x6356041a, 0xc79f965e, + 0x101414b9, 0x9163cf8f, 0x6ddd04be, 0xfb8ef4be, + 0xd7ecdacd, 0xa5ee3ff8, 0xf5570774, 0x509d4f80, + 0x8eb2d2bc, 0x643ec00b, 0xbc6f905f, 0x2cd7e906, + 0x3d1fa19a, 0x1399ec3f, 0xfdf2112a, 0x98d345ac, + 0xa7a910ea, 0x293a245e, 0xc74325bc, 0x4b909676, + 0x0ab4ae0e, 0x991b3209, 0x241b8fb7, 0x9f94257e, + 0xd64c12bc, 0xe2a5be57, 0x45da5e02, 0xbfea50a2, + 0xa3361760, 0x29139e74, 0x819f989a, 0xdd98b860, + 0x21325422, 0x2a025d7e, 0x176ef2ff, 0x05de7660, + 0x5399386a, 0xd440706c, 0xc5af0e1e, 0x28641a12, + 0xce578056, 0xa2deceff, 0xaa67202b, 0x2a032659, + 0x7f9995e0, 0xc72437f6, 0x7513a59b, 0x802ac738, + 0x240675e6, 0x2154dcdd, 0x8b5c620a, 0x0577c125, + 0x666cc6ba, 0x811d1b86, 0x5e34b9f5, 0x6f8916f1, + 0xc5d42c2c, 0xcaf5abcf, 0xe5e67066, 0x36cae7c7, + 0x943dd32e, 0x36fd7344, 0xec4f6b4e, 0x201b928a, + 0x39f0374a, 0x3e49bd37, 0x65146b92, 0xa8b1386a, + 0x5e1a8048, 0xc9a6e41b, 0xe9b0d77d, 0x34ab1250, + 0xecbbb7a3, 0x1e11f130, 0xddbb5b46, 0x0b9ddc16, + 0xfda8ada3, 0xc47a164c, 0x3aaa4ce8, 0x6f20a7ff, + 0x02f0b980, 0xcc49fc4f, 0xb349d19e, 0x9106422b, + 0x1d2accfd, 0x0a2316bf, 0x0e6fdfdd, 0x7532d530, + 0x40036590, 0x615ecb90, 0x781b6728, 0x8c66fe14, + 0xb00e7821, 0x9749c736, 0xa238ed12, 0x101080ab, + 0xc84e4079, 0xd279d31b, 0xfff2cd9c, 0x2d0f79cd, + }; + + private static final long[] hashLong1 = new long[] { + 0xbbfc7f1f6f7f4177L, 0x9f36441299446e8cL, + 0xa09d62716a0b898eL, 0xfba38a87518bdc0cL, + 0xbb6a0ccbd4180225L, 0x8087261f0f9f02b4L, + 0x17e7a0e7a483a784L, 0x8ffb90f730b1926fL, + 0x3a99a2bf6ce3883eL, 0x17569cf129edc380L, + 0x39de644a5f3c6021L, 0xa1cf03811449a778L, + 0x8adf18418bcc0ce6L, 0x32ac4e6885dc0c5cL, + 0xa9a8387f7bcc8346L, 0x6a2fd1348fe5afd6L, + 0x5a45319763215d65L, 0x2b472d3db4ee6010L, + 0xe0ea2bcda4004974L, 0x917a9ba08b4bbbe0L, + 0xbdef22231b3d1c7bL, 0x99ad09e78c58dc11L, + 0x0e786c0a6d626b1fL, 0x9e425cf1e084c4e0L, + 0x73e1b36b2cea09ceL, 0xee0f4ecfcc5d9e17L, + 0x4f7f96efa6f3d6aaL, 0xe1b3154269f161c1L, + 0xa5aede0147475ab3L, 0x0cb9a679715a5ff2L, + 0x63bd0c12ac13d310L, 0x4da62908aba8fa5cL, + 0xfc156bd125b71cf0L, 0x22fbf1c736331bbdL, + 0x29e770dd5538035eL, 0x0595a383b620aec7L, + 0x9dd41884946a836aL, 0x678519a538ce1394L, + 0x9e2ba8d88fffe54bL, 0x292373f97a0c345cL, + 0x84d2b45cbf70dfefL, 0x943617b3b49ad5ccL, + 0xdf2d60eaf53862cfL, 0x7cde290a887b4758L, + 0xa66725bdb4a21b6aL, 0xa9a1ca98da213586L, + 0x80cbc3932fcaa19eL, 0xcb099548f80d62cdL, + 0xa030e9863c1720dbL, 0x87374cbdefbc5ed4L, + 0x43d72258ee2daf0eL, 0xce8f8a9882ffc32eL, + 0x1b84df12eef07355L, 0xe03054955ef389d0L, + 0xa5e268803e7f140aL, 0x559802e90d6dc750L, + 0x6ba3e52171986887L, 0x317f65554e3344e4L, + 0x81291385e2c2e221L, 0x63cc077cfcba77a8L, + 0xe1a69f35b12346e6L, 0x28dfeb67e61abcedL, + 0x7d3cc36d4d8bfee3L, 0xc462ba3057e5ecddL, + 0xee8b691796e7d908L, 0x304731e13a6db848L, + 0x798b88608089203eL, 0x3a34c3d9d7a505b9L, + 0x36575c8376b297d4L, 0x4cb1aaecf40679daL, + 0x60ae7ab71c141f12L, 0x4c0f41b10523535bL, + 0x86302b26845bbcfeL, 0xb24f69eb9b72b7a5L, + 0xfed4b4aac50a4192L, 0x951156ac8b4fd213L, + 0x6644c53d4e18c1beL, 0x6356041ac79f965eL, + 0x101414b99163cf8fL, 0x6ddd04befb8ef4beL, + 0xd7ecdacda5ee3ff8L, 0xf5570774509d4f80L, + 0x8eb2d2bc643ec00bL, 0xbc6f905f2cd7e906L, + 0x3d1fa19a1399ec3fL, 0xfdf2112a98d345acL, + 0xa7a910ea293a245eL, 0xc74325bc4b909676L, + 0x0ab4ae0e991b3209L, 0x241b8fb79f94257eL, + 0xd64c12bce2a5be57L, 0x45da5e02bfea50a2L, + 0xa336176029139e74L, 0x819f989add98b860L, + 0x213254222a025d7eL, 0x176ef2ff05de7660L, + 0x5399386ad440706cL, 0xc5af0e1e28641a12L, + 0xce578056a2deceffL, 0xaa67202b2a032659L, + 0x7f9995e0c72437f6L, 0x7513a59b802ac738L, + 0x240675e62154dcddL, 0x8b5c620a0577c125L, + 0x666cc6ba811d1b86L, 0x5e34b9f56f8916f1L, + 0xc5d42c2ccaf5abcfL, 0xe5e6706636cae7c7L, + 0x943dd32e36fd7344L, 0xec4f6b4e201b928aL, + 0x39f0374a3e49bd37L, 0x65146b92a8b1386aL, + 0x5e1a8048c9a6e41bL, 0xe9b0d77d34ab1250L, + 0xecbbb7a31e11f130L, 0xddbb5b460b9ddc16L, + 0xfda8ada3c47a164cL, 0x3aaa4ce86f20a7ffL, + 0x02f0b980cc49fc4fL, 0xb349d19e9106422bL, + 0x1d2accfd0a2316bfL, 0x0e6fdfdd7532d530L, + 0x40036590615ecb90L, 0x781b67288c66fe14L, + 0xb00e78219749c736L, 0xa238ed12101080abL, + 0xc84e4079d279d31bL, 0xfff2cd9c2d0f79cdL, + 0xdab62d66c06279ebL, 0xeaa2710d79013442L, + 0x4befae1933ae45eaL, 0xf742373ef5e86e15L, + 0xb8e5f84e3cea704dL, 0x4573594c0b2c0d74L, + 0xd7f0b3d0cea44c5aL, 0xb124cb6a4e5b5fabL, + 0x26111d64cfd617ffL, 0xad7e33874100b791L, + 0x818da184e5c197c2L, 0x3e3dbe3bfb64d8d1L, + 0xef65f7bd56b98227L, 0x43586bdb8ea8b5d3L, + 0x1ca4ffc02102b23aL, 0x7ae45e72bf689a0fL, + 0x0594bd7fbe4901feL, 0xc52672b6658424b7L, + 0x8c04cdf85ac90c3eL, 0x239d107ffdcd7875L, + 0x664bf16896483553L, 0x220ad696a44ada92L, + 0x637d193a3ff2e9a4L, 0x9488dc4f88b3cd23L, + 0x67589036540456dbL, 0xd7271e4a57deb4c6L, + 0x5c41ba8e3aa74cf4L, 0x7ab44fb4e4f4dd9fL, + 0x25e7eef30d4ee084L, 0x612ae65f0700bacfL, + 0x168119ae9c518ea8L, 0x56249ed78d2d7790L, + 0x1d6297235e22f635L, 0x331dc499a5603043L, + 0x4bc518ceb8c5ce57L, 0x060c2499594bd0c4L, + 0x9aa82b188fe399d6L, 0x6cc1c0fc8eb73db4L, + 0x072279da2b6973ddL, 0xa939e061471e8ea5L, + 0x7006ffac58138d74L, 0x5077cf7baef3aaf1L, + 0x9c59d7fb5a25423dL, 0xbfb2343bc051af96L, + 0xd171aa1646d2b538L, 0x7a4868332077a952L, + 0xf655509c0190b68eL, 0x11fae60a944a5116L, + 0xf5e91274cffcc423L, 0x67111adb3e2c3430L, + 0x02d5caf5d0097944L, 0x2a269dc3606b6bf7L, + 0xaa898f96056e21e3L, 0xb7ecf7ed802a0636L, + 0xc2de066715521379L, 0x4d61b418e7d8d3d8L, + 0x762ecf16d32247d1L, 0xa368a79a14784f03L, + 0x8a17ded4c070a9cdL, 0x896d0c1ecf207fc4L, + 0x55903b97ebbb2e62L, 0x1ad41a47e6314d60L, + 0x66180f8ce1ec33e8L, 0xeec3f3a48d518d2fL, + 0xbe94b7d579327727L, 0x5befbba66d60d9fbL, + 0xad512c1b64c36e4dL, 0x3f085b65e8f9a2baL, + 0xfb090deef039fbfcL, 0xeea07925bb195095L, + 0xa13a35c51de79520L, 0x00c79980859c90b6L, + 0xfa0b2b89e178728fL, 0xa57a654287a8e0d6L, + 0x70dc2e947eecc279L, 0x5c1b55993e03048dL, + 0x3f96de3aba3c990aL, 0xbf9869dbb45f1eabL, + 0x0445531fff32b763L, 0xb2c742a9a67df43eL, + 0xb46ed314a7718d54L, 0x137bd5869e12a240L, + 0xa80e94b6247fac64L, 0xc20c65e6febaed75L, + 0x4522eaf6f59ebbb2L, 0xecb0c3d5a781f337L, + 0x1596656b0a381a67L, 0x44dfd187386e7cd2L, + 0xb05ff15ee95f72b5L, 0xaf8691414fa6282aL, + 0x33e2b446b0dfa8e1L, 0xbcc261d8cdba8d73L, + 0x5ba3e44dbcd15dd7L, 0x48c783c088482a8fL, + 0xad77eaa490d5bd5fL, 0xee086cffcd911dd5L, + 0xbb33bb7bb06e4db7L, 0x676d68759099fb7aL, + 0x628d0941c2abe433L, 0xd7d703697db4c870L, + 0xe097bb123c7002c8L, 0xcb5464eb72a41b8eL, + 0x078e8ae39fdd333fL, 0x6dc7773b93d8acf0L, + 0x0145c769636837baL, 0xaad16c1c7fc4c317L, + 0x44cfbc770a7d8d98L, 0x74ee0486bd3dd142L, + 0xbca23c29c93e7770L, 0xda766748842cc1e9L, + 0xe031dc258f8b8e19L, 0xcf540550c8f812a3L, + 0xcad3f3e879de1c90L, 0x63d447dad1682dbeL, + 0x6a1571e11a9e2458L, 0xe394a133401d6259L, + 0xf6f67baede562b1fL, 0xee74d768ede4a0e6L, + 0x0cce398025ee7c03L, 0x6c2e9586084d7572L, + 0xc5ffd02d54246ff6L, 0x3dc8df5a90380adcL, + 0xa30aa36fda41db08L, 0xc47c04bd4ed068f5L, + 0x69c6c19c03298379L, 0xf7e68914321f7997L, + 0x53ba2097a05cff8cL, 0xe2389fcc0fcaae04L, + }; + private static final long[] hashLong2 = new long[] { + 0xa6aec10e1d4df188L, 0xe6dc67633a9eea54L, + 0x99345a9b6b423866L, 0xb90a0dedcdda1738L, + 0x0201106317c6af69L, 0x239e964a342fc478L, + 0xd71edc978924402cL, 0x34b491f73540a37aL, + 0x01ef660726bad636L, 0x5caeb55704d40701L, + 0xe228a6c60d31a267L, 0x180286dbed82243fL, + 0x909b561fb46e935aL, 0xc7396b077a2776bfL, + 0x046d073f1984d635L, 0xa9751f6dd7e6a6e2L, + 0xc3c87012235843cfL, 0x6c877f4d094cca72L, + 0x194e19c882cb4e2eL, 0x123035f834e0ec18L, + 0x383e7b7e5379c162L, 0xf53caa6d1e1c41c6L, + 0x259ed1e98d804e3fL, 0x59887a40360f6e8dL, + 0x97cdcc0f9396cfc5L, 0xab0fe6924768b20bL, + 0x58e240c447a84e1cL, 0x3ac69e78271ffbfcL, + 0x6317b5d2c8fbed09L, 0x1e4aec0b7a3f7274L, + 0xc378d18f10c62dd7L, 0x606a37f5067184beL, + 0xb52dd57583cd4a48L, 0xaa72f57a84d0fdc7L, + 0x083f6692fa82624fL, 0x638450319fffe4aaL, + 0x8464e232edf51184L, 0x64ad1ff23a831ad7L, + 0x71fd43bac78535baL, 0xffa74c0ba481c1bbL, + 0xee6a20cdcb30b89dL, 0x7546247109529dffL, + 0xd2b640223d821fb2L, 0xc47cdb63690fd231L, + 0xed10c251fba68142L, 0x8df01a3ea17cfaa2L, + 0x4146c514fbf3fdd3L, 0x0aecf44ed25bf0e1L, + 0x664851a0780c8ca3L, 0xc75a92da42d293b7L, + 0x1059193410835b1cL, 0x44a152e721ecb239L, + 0xdf84ab1c187d88fdL, 0x451a5f6bedea3d16L, + 0xd89f346bfa49389bL, 0x3ebe0e05e9f6e0c1L, + 0x3b2cf15a1bac06e9L, 0xc98ab68b4b9194d4L, + 0x7b524a73f3dd5095L, 0x365f100db06d6054L, + 0x0cec1e9094b0b654L, 0x3d300ffedc76a42bL, + 0xd69285fe553caeb1L, 0x7a94f1c5bb5ed9ebL, + 0xd05fbd88e26477acL, 0x453888d84f12ab1eL, + 0x5eace5daab2fcc61L, 0x1497003c9c2bf6a5L, + 0x31ba2ba0e7206fa2L, 0x70b50bc693a9c70aL, + 0x6f15b56d74586164L, 0x65772d6094f37602L, + 0x04f54443aacb946aL, 0x3d7d8a94152e8672L, + 0x73f301ef74f9659dL, 0x542385d1e9962109L, + 0xd47a7c4dcc41fdefL, 0x329b1b96078aec8eL, + 0x91dfb6ef859a4ca3L, 0x4d88d99232791408L, + 0x41b147b34bea31f1L, 0xc86efc0c6ee71fdfL, + 0xd6f9b8599b49f597L, 0x466d71c7f4689ec9L, + 0x450b4961a5fd2ed0L, 0x9822c8d3fe40156eL, + 0x1918a141890dccbaL, 0x953c36bb807f4511L, + 0x7c0fc3163766e05bL, 0xb63d53171e2a7e64L, + 0xf5b4e6a0d7e01551L, 0x3d33fa08233c7373L, + 0xdcc5b88ccfec7962L, 0x539fb2d8e5cf6d42L, + 0x742a54a6f51381d9L, 0xd6ab2350b7a3f0d7L, + 0xee1d7a45020a6216L, 0x3ed764c9596fa971L, + 0xae6af0f79f1d1c26L, 0xedc137414b889fe9L, + 0x2cfcf5ecbe24df95L, 0x08567bff66e6b02dL, + 0x71ac8bc3ada42249L, 0xc140f24ee4b4d1b3L, + 0x6c867ecfa2e0a494L, 0xff3476fb0a2edf77L, + 0x0dd6349d0f0189efL, 0x590427ac9ce4bef9L, + 0xf09ced7396d25396L, 0x741192e9d6cf6266L, + 0x8f1b4951fe3acc3aL, 0xcac57ea2aa24b8fcL, + 0xb286ee27619f665fL, 0x7cdbf613130d6916L, + 0xc02b68bffc72d45fL, 0xefb918460f8ee36dL, + 0xb4633bd5deae803bL, 0xa331d967889dbcc4L, + 0xa273532100769980L, 0xf08c95baf5c5e81aL, + 0xa7060b9109b09862L, 0x95a2b32abfc42dc6L, + 0x9ecfdccaa9df23efL, 0xe1762e54953d406eL, + 0x550d5716fb24403dL, 0xd989c5e539425db0L, + 0x0235cc82bd3a1ffeL, 0x3bffe43a80a31c65L, + 0x2080737ab8fdc16bL, 0x4638ed996f733f0fL, + 0xba38f498b164c089L, 0xbdcaada09aff30a3L, + 0x6dfa0aeabdca45faL, 0x0db99b572f3f3d4bL, + 0xf283ec1affe940aeL, 0x656b8271d93a2098L, + 0xae06fe4472a4f4e8L, 0xa3d1ba8231866533L, + 0x172ed4a4f02fe618L, 0x4da05d5cda8e1d8dL, + 0x07a97f0e9bc904ceL, 0x30737b9826582814L, + 0x923a866e6f5193bbL, 0x24e913dafab512b8L, + 0x88711807315c2221L, 0x100646c268490576L, + 0x83209b884e2b4150L, 0x6d0e1e79262b1d63L, + 0xdb8bf5fa54d17600L, 0xccb890f82fefc318L, + 0xe3eeb54bd5aafa16L, 0x2f95a4e747ae89deL, + 0x9bd241203c7cb9b7L, 0x11eda9e343b3214cL, + 0xbb189411a71fb825L, 0x589dbcd5a971356aL, + 0x7348f125fd65d77cL, 0x84a34a294984f9f9L, + 0xa172ebf3095229ccL, 0x901f2330620142b4L, + 0x42c153590e9ec828L, 0x8df1b2ee5a9fb06eL, + 0xb474c5e0ef73731eL, 0x9617bb6f8498537dL, + 0xcae6f172b943509aL, 0x4b874a9892663e07L, + 0x2259dd17d52bb856L, 0x8bb2e20ffde3b727L, + 0x9386684d60fffc03L, 0xf5f3c89f97af043bL, + 0xce3cb76b8e98f868L, 0x955f3c6fd908af6dL, + 0xef18b918ef8eed1eL, 0xf7b5f83753f8a95fL, + 0x3f398d6b5fce869dL, 0x20585f3682009304L, + 0x8b7afb161e3ef724L, 0xe2ed434d67dd043dL, + 0xd2e49ce6f29915c1L, 0xa463ff4b2a4b7b5bL, + 0x1565ef010814e0e4L, 0x4b42c4843dada479L, + 0xf2f74737234cfd5dL, 0xcd791c486fd5b580L, + 0x71e79bfac749f612L, 0x31d5a4ffa04325e0L, + 0x33cc21a9a65d99f8L, 0xe0a117c507cc201eL, + 0x8a60010647b32134L, 0x9d18c8d41f82ceddL, + 0x56ea4a102d69cf1fL, 0x2cd88e81f714ae1aL, + 0xcbadc657263b36a8L, 0x55371e2283702c4aL, + 0x350aaf93d63607b8L, 0xcf352ce8329baec8L, + 0x83166a782dae95eaL, 0x72ec0a52da296d90L, + 0xe28ddb6247bf6570L, 0xd3586cbcb542c8b0L, + 0x187646ccbd5c00ceL, 0x7a2d39eb2013f85bL, + 0x3701d189ec08d507L, 0x041b1101fa99b6c0L, + 0xd2bbb8627ed9db71L, 0x41888633cd0f3402L, + 0x173ff9d4f6e5e830L, 0xedc36a1daca118feL, + 0x2ef410396b4e1a13L, 0x76f18315f6f989f6L, + 0x684e266116154fe5L, 0x5816a210e2094ff7L, + 0x1fce1bc0297616beL, 0x2c91c1a3be5fb2bcL, + 0xb326611b438d5de6L, 0x4d2541fb5362838fL, + 0x00af13266e318cc7L, 0xefe7ef7665250d40L, + 0xb0649f79ae72acebL, 0x09a6e1e525ad93ccL, + 0xfcd8529bde730479L, 0x24345ff359e404f5L, + 0xeaa7a9e6157358f3L, 0x11c0dbcc0fb61dbfL, + 0x2228e499dc9d61ebL, 0x8dc54a71ea828fd0L, + 0x25f238c604607449L, 0x47353764eab7919aL, + 0x67e9126ad9a96527L, 0xcf67f8474fee93f3L, + 0xb5144e14b446c45dL, 0x4add93f590b22e7dL, + 0xdd14c5fc63a8baa3L, 0xd9a625172b60e01fL, + 0x6d44d12f70b45c13L, 0xfa0858692625295fL, + 0x88af4f6e128bc06fL, 0xc931aa96e71db2caL, + 0x99a24176639e45e3L, 0x1a60456d14d4d164L, + 0x452e48c1fec8e686L, 0x2afba83c251c70f1L, + 0xb885bce52f7c1906L, 0x970bea59e6b9cfddL, + 0xcad670d9427d5596L, 0xa1224b4adecebc37L, + 0xa153e6b3a19b0027L, 0x7cd420001e0501daL, + 0xe2c858628f977065L, 0xcc49d64dc72d1115L, + 0x7b1134d5b8e22d7dL, 0xaeef61b14f752133L, + 0x2ad7e1c36bfd7953L, 0xac20df4784a0b970L, + 0xe63bdd7b403c884cL, 0xc8d60bec2ce1a1b3L, + }; + private static final long[] hashLong3 = new long[] { + 0x934a05273d9302afL, 0x464bdc2df211f8fdL, + 0x546fc76c814e1cc7L, 0x3715ade74365d24dL, + 0xed78b65833d95083L, 0x24e638971cce038aL, + 0x5969e63166fd9f67L, 0x4bb1f8ddc27833adL, + 0x681c0891ac59a643L, 0x0b7007a9df2d6c04L, + 0x0f5ff79ef1afcf24L, 0xdeabc432e3ae279eL, + 0x8213aae8ae30bba8L, 0x002ed49ca24733a9L, + 0xb9a624b4a18698dbL, 0x646e26104d850795L, + 0xb70ebc47c8d909b8L, 0xc816949c1245d930L, + 0x673b1b34bdc8ec24L, 0x22ad1cb910993a4aL, + 0x423da30fe15bda3eL, 0xc0861200eee93901L, + 0xf092386b3dd050c1L, 0xd450f0bce346877cL, + 0xfa0a86fd2f8f71bcL, 0x03f81787e99176e1L, + 0x125450a12cbf6f01L, 0x375e09a486b48e5fL, + 0x893c24a809af63a0L, 0x62b0e5f15f0c1b0bL, + 0xb41a1960cbf05060L, 0xc9b56e9147c49b09L, + 0x6dec5801daf41404L, 0x15ffd01cfe7b899aL, + 0xc1effa88aaef187cL, 0x728aed3de66f84c5L, + 0x22c947ef66e97ffdL, 0xdd04647e08e2d319L, + 0xb132bd70424fec0aL, 0xf2a137e27292b408L, + 0xf0b410f6eb11b780L, 0x416f2a3a44c13104L, + 0x1dac9748e6f5efa4L, 0xe52c004172ab1300L, + 0x560afa71a892d1efL, 0xbfe27e1b915604cfL, + 0x66419c372d809460L, 0x5e33681849f1044fL, + 0xd4fbea56e2a062acL, 0xde63ea7f54919e62L, + 0x7f6d0ee58d77c8e3L, 0x5a210543039f8a3dL, + 0x2ab6e538f3e57d3cL, 0xb89c29892b1d9711L, + 0x1f1717e16d3f6923L, 0x7f6993dd214f2300L, + 0xe57104f184fab993L, 0xb80cd70cc0799b09L, + 0x8563ae2279acf186L, 0x76ebd62de4a9de55L, + 0xeedaaa01df7744f1L, 0x0075b98d6c07b63cL, + 0x6845e255d6d48dfcL, 0xac014d84fe8309deL, + 0x23fb0df1c40f91d9L, 0xdfa1bc16f5378799L, + 0xe628de7d565d0a29L, 0xc6fe30331d3018d9L, + 0x38656c25c54a83abL, 0x7da985d7058a0105L, + 0xbb3bf875900dbda1L, 0x58c146c6a819cb28L, + 0x7b5cb1b0a6943fe1L, 0x14f7952b3b7edf54L, + 0x4d1498157ed56f32L, 0x623b7f0ea3bfee88L, + 0x74f8d1be90c15660L, 0xa9bea58ce5fccc65L, + 0xd8df69c73a069f8eL, 0x89e7b4ff0766fb45L, + 0x9345a29a66a3a896L, 0x208c599e9c6358a9L, + 0x7fcdf4041284d57cL, 0xfeed113c4625764cL, + 0xee17779fb2fa870fL, 0x73ff78ed8a49badaL, + 0x4183fd4a27ac2a62L, 0x33419c8151384175L, + 0x41c1e05550e179f4L, 0xb19c033656e61f87L, + 0x014b1aae53853ab8L, 0x3f091ffe7696ccf3L, + 0xe95775eee22b3166L, 0xa12517dc77af73c9L, + 0x644e9e0bfd2ea40bL, 0xfa061a21c3883611L, + 0x6be0294c47a6d80dL, 0x26f6596c8ebff582L, + 0x75fccf2c98968adaL, 0x17dcace9ec9ffa3bL, + 0xa3ead2e0ac8458ebL, 0x180032177b31ab93L, + 0xd01b915bae1f1ffeL, 0x2b6a550b4223a09cL, + 0xa1738abca4e966cdL, 0xfc5080754d2b543eL, + 0x2ff13893966717a2L, 0x99cde8051e41380eL, + 0x22a7856a61563c58L, 0x5558a26a9ef50d71L, + 0xf80c1900a41dd96fL, 0x83df0ad627443946L, + 0x03d1a237765d8c64L, 0x74589f7f9938369cL, + 0x613555ac9cc9c2b1L, 0xbaaa67aa70576faaL, + 0x01fff70fd954892bL, 0xbc989bcefecc05a7L, + 0x38a9302b797bb34fL, 0x2db5950470d06cecL, + 0xc918eed8a8682eafL, 0xa62487566fd9571eL, + 0xb5216bb21d82db05L, 0xb901bc30f5860c7fL, + 0x1a071ab2e2e02ba3L, 0x1a0cf40956330b70L, + 0xf4dc8d3a73d55da9L, 0x73368fe76fc5856eL, + 0x14d063cccdd245ceL, 0x912666015285d16aL, + 0x1946d15bc03ed292L, 0xfd31019016e5aa93L, + 0x2013aeb2b2b3572fL, 0x39089d56736af3edL, + 0x3361887df8e14122L, 0x83732ba4ec09be08L, + 0xa92e24d8726cc57aL, 0x9027e4973e8498a2L, + 0xe12d67c09aa9c7e8L, 0x8e56c3d257c67c2fL, + 0x73c5fba6dfb9032dL, 0xe5c298286469825cL, + 0x036fd336e4bee73aL, 0xf4e6486652a5653dL, + 0x08db1ff9a90b6944L, 0xca0bf5d4377a1053L, + 0xcf058487f43ff71eL, 0xf1cb5b1e797a3c67L, + 0x8f996501cd47c158L, 0xf233d4a4b05dd79cL, + 0xbb21b60a13285099L, 0x3ab892325c60be5bL, + 0x4f882097736bcf4aL, 0x586114cf2b221ef5L, + 0x989476aeff622b7dL, 0x811c30026962c0acL, + 0x142088456e56d53dL, 0x9af524cbf396f084L, + 0x0ca2c3a939ec79f8L, 0x5ce4eb22b1961929L, + 0xc9f319833726ac39L, 0x239a2076e761376dL, + 0xf614385ddd7ec368L, 0x7e120f77dbd788cfL, + 0x960dacb853d26607L, 0x354be4b31fc4c60aL, + 0x587fcf05e62af1a0L, 0xcf6fc6432e6e702eL, + 0x65e5b7807c0fe901L, 0xaaa49b2a72b19037L, + 0x05568acb6f2466edL, 0x3efb19683692b61cL, + 0xf0c8512fe2e6baceL, 0x4faff750f200227dL, + 0x4deda52b2223b6c1L, 0x3cecf2d14879b43eL, + 0x2f6ebc70897c54f1L, 0xd100289cde7e3154L, + 0x6210fdaaa729e85bL, 0x3d40b506a2130705L, + 0x2e361cf663f82506L, 0x82e406fdda8f698cL, + 0x22e7ef03e05ade2fL, 0x0501293266d17d75L, + 0xd42c4300d8bdf5d4L, 0xeb85550f5b790dedL, + 0x23a110098b5c2cc2L, 0xf945fd7e863b97bcL, + 0xb4a174ddd8ab2d15L, 0x06ea917e39d3bb21L, + 0xc3871754b3fcdf2fL, 0x0dc5db8199f6d247L, + 0x5f01ff5d34b3a1acL, 0x166bc4f92a034cf0L, + 0x5fa9233398994552L, 0xeec3d4da5aae59feL, + 0x90c0fd56e225c732L, 0xbfecb404b3255280L, + 0x5be99c5cb953c344L, 0x7c432dac6fbb7e43L, + 0x943b9f9495c0bb5dL, 0x13147b10841c9c07L, + 0xe45e590bc8fe09cdL, 0xb9cec54fd871b22bL, + 0xbf696c3bff978b8cL, 0x90bbc60b72b388c1L, + 0x2a4ec3e14b1b00bfL, 0x1117ea10c5e83086L, + 0xff64d065cc3bf148L, 0xd2d35ce5ec88e243L, + 0xdb7959918eac3321L, 0xa0c4ea4dd11ab5c0L, + 0x81506848e3141a3fL, 0x0f603b0bd561b341L, + 0x52ed5eb3a7be6280L, 0xac517f389c81c5d1L, + 0xe0410b1618f29bffL, 0x9297da3e9540dd87L, + 0x630570faa1303d9fL, 0x6fd64f132eb6632bL, + 0xa621690ce8bff50fL, 0x7e9c76858c375c17L, + 0x621b35fe64246884L, 0x72661260a3561b01L, + 0xb226cfe4a00c2299L, 0xca0804870977311cL, + 0xacc14f9338c47c70L, 0xfee7f38ecc33fc6eL, + 0xa10f5ed230711e23L, 0xead1b76ff56c5516L, + 0xa4bff2c4a126ce25L, 0xdbe54e74ef71d542L, + 0xd9fa2f75cbb53ec0L, 0xa7cb72ad3228be52L, + 0xc6d0b432e2a96875L, 0x259929d738d755b3L, + 0xd9cb10d4b208b0eeL, 0xcd60407482989e40L, + 0xf8675fd64001f059L, 0xf2727afa52402721L, + 0xef9fe7079b4d9dbeL, 0xb7ec7278e459c07cL, + 0x36c5526cb90d0793L, 0x365cc236bf674380L, + 0x68bd383caec232e9L, 0x55d20ef3ccf92f3dL, + 0xe3f1955f8048504eL, 0x93a0f72f27ba104bL, + 0xad754dc2cfa2672fL, 0x672ccba6e1c76af3L, + 0x7e1ba1816afc418dL, 0xf8c2f834bc76c3d4L, + 0x4a18adbaeb27cb8bL, 0xc3ce4be983cb4580L, + 0x815fcdaa544df6b1L, 0xe0627d2f50692f9aL, + }; + private static final long[] hashLong4 = new long[] { + 0x3d9dceee78d124ceL, 0x63231f1004bd7dfeL, + 0xa6ffefa1b010fdb8L, 0x16963d05f3bfa5b4L, + 0xa2af49670fcaddc4L, 0x4e6137e1fc6662e4L, + 0xb00247450f28a978L, 0x04eb31042bfa0a44L, + 0xb1072cb8fd2ba71fL, 0xe50f2431baa145baL, + 0xeb3aaeee3cad3246L, 0x8cd9d05c349fe106L, + 0x6719a082e891134aL, 0xf7f35a23f3814a43L, + 0x9141ac68bab0d9caL, 0xd8291a4e34994b8bL, + 0x68a2ce9cb785bc6aL, 0x8e029db415d1f141L, + 0x9827aa1f23f59eb5L, 0x8332de07239b5623L, + 0xdaca1189a62f52f1L, 0x9755d746357fee3dL, + 0x7d53e97f39408b3aL, 0xbed70f3d730b9fa1L, + 0xd51b0406736e062cL, 0x93865ee439da206aL, + 0x16065302c7fee079L, 0x3041937683e4c28bL, + 0x424e96e3f9386932L, 0xaa94979097d0185dL, + 0x0950d79be38cdd67L, 0x567bdfd361c0a0a3L, + 0xf02a97990a2bd3d9L, 0xe46713cad8dff011L, + 0x3ea3639906e14983L, 0x5625e3ba2621d7b6L, + 0x20bd0b95a6d2adfcL, 0x9972ec00757d49a6L, + 0xf758d4f9acf2d580L, 0xe251ebf512466699L, + 0x38a6fa0412d76d4aL, 0xd5831786675c3193L, + 0x60ba9574c93315f0L, 0x4b79e941435efc0cL, + 0x8c35891fb4c7b04bL, 0xbd6bf8b27fdb3651L, + 0x65d13331049f0a21L, 0xd9f528dcb2a36087L, + 0xd13225d1e45d459fL, 0xbb1bfd40f73644d5L, + 0x34174041349768fdL, 0x3550388a1f361384L, + 0x3f8181878f62b29cL, 0x456d71709e823cafL, + 0xb7693f87ed1a6a5aL, 0x9d3cd1d8cce944c3L, + 0x64bab64ab261c691L, 0xc854f31a188c977fL, + 0x2af24165f68b94d2L, 0xca8992b1f06ed6e2L, + 0x64a79897cd48a3e3L, 0xaddcb78dd1a204aaL, + 0x56042422685eee3cL, 0x85582d525f60f2d8L, + 0xec1e18cba1aaef83L, 0xf76afa7f9fed90c3L, + 0x487fe350c0f53531L, 0x35f1696eee43be51L, + 0xa92f917b4361d8ceL, 0xb7b7dfe5f8cba237L, + 0x8d0987e4bc31fc4eL, 0xe12618522f8e8f5bL, + 0x175b5eff404dba4bL, 0xca0438f39b8c3a64L, + 0x59fb015e811d305bL, 0xb6f15c269e431cfaL, + 0x8f107ea45d937791L, 0xea133bc3d83703feL, + 0x4a53129e5be5f397L, 0x59cee7c834e19720L, + 0x24aecf1821e63a2cL, 0x43848b6cf6e063e6L, + 0x11ca361711966844L, 0xc59e0cc984cbd9c1L, + 0x03cb500744f71baeL, 0xabb64d4862207042L, + 0xf4ff2646ad3bdd40L, 0x006b5c2f782b4875L, + 0x4d48a0bec1612c1bL, 0x32b68fdd560ca658L, + 0x960f267b7dd015a1L, 0x80132ad32c2de883L, + 0x364d2f9b4c7ad645L, 0x76d78cd19ed0361aL, + 0x735079092e50544dL, 0x15044cb4ab7f1f26L, + 0x46ffdd4bb9e9fe35L, 0x97af2b3cbe3fdcefL, + 0x8fd153bcb3ff1b8aL, 0x919830efed8d20e5L, + 0xc566afb69d2ccddeL, 0xd4cd4c88165a9168L, + 0x99416ddb8723c56cL, 0x323f2414818299d1L, + 0xd21c9012e64058e5L, 0x8730b388b89efe66L, + 0x59b6682acf4e57b1L, 0x6234c68966a0b74dL, + 0x9917764663c7eb13L, 0xdd832988153e3f23L, + 0x0c3e5313c90bec00L, 0x36ac71c8404939b4L, + 0x3a8d5780947c807dL, 0xab29d0dd150cbe85L, + 0x0154c8959efe6bbdL, 0xd549bf694fd64604L, + 0x3cb1e5ff0eb7adc9L, 0x0f3de44f6e233bbfL, + 0xfac50e371c3547dfL, 0x4d55baee3f78ba88L, + 0x480f862a5631d924L, 0x70986af77ae9d9e2L, + 0x55d64ed0f8046ce0L, 0x741d6e7c991ee736L, + 0x00903b4710f11a9aL, 0x7f83a2aa8e127359L, + 0x3f1ccfb322f08e01L, 0x102cc80801e73db7L, + 0x37cc0c100f983aacL, 0xac2685ca45924c64L, + 0x980a934584ce70a4L, 0xbd362b237bb242bcL, + 0xc1627f7914da0788L, 0x4abdbf95ed5743abL, + 0x52509a6ba7b4461dL, 0x8c5bbea5069ea694L, + 0x2521dec1e4759c0dL, 0xafc35a758f84a37dL, + 0xca87e01704076b54L, 0x19894a5dd71d0354L, + 0xaeb69dccf22b7cbbL, 0x2dfe977c0968106eL, + 0x962c2d5e0d9355a1L, 0x9966899bf3ec26f2L, + 0x51baa952625a6a5cL, 0x7cedce8598a3039bL, + 0xe0eddaaaf5f2adbaL, 0xfcbe1fbe55f26432L, + 0xd5a9e1bff0ab5ad7L, 0x81eebec9acf07783L, + 0xd11c814b584b41dbL, 0x150ab35064ea8264L, + 0x2ad0dd3e55d3a6caL, 0x35cb541b3220da09L, + 0x5327ae81a48fc423L, 0x4a96cb8e24992c03L, + 0xd07d1edaaaca55aaL, 0x3575818f7bada97dL, + 0xd3325ffe2ffd4dc9L, 0x13f4e15e015da4f6L, + 0x2b380c2325116430L, 0x41da470caebfe34eL, + 0xa4b39b91fedd7bd4L, 0x00ae47a8d62ea0d0L, + 0xee146a4188110d9cL, 0xebf370cd62585a19L, + 0x32f857e4447bbf13L, 0xed8b078fd195ba93L, + 0xecb183b71e6a674fL, 0x3d9554ae1d2151feL, + 0x57ab954f9bc6a429L, 0x7febb1479ecb9770L, + 0xcee32ccaa677718bL, 0x999080a59f43ad76L, + 0x86d0ad2cd01112aaL, 0x485883e72c70774bL, + 0xb0f23e2d51d69c4cL, 0x0e7337d9aded4ee5L, + 0x51c8398fe044969cL, 0xcdd3b0002c41ed2eL, + 0x1af3553fe0e681ddL, 0xc6e70366337b9e6aL, + 0x50736b540ada5d63L, 0x3bd35204b513b744L, + 0x3d1fcbc3566fae3fL, 0x1bdaad4cb44e6986L, + 0x4e8177eceb77a4d7L, 0x9c6b4301916e1badL, + 0x3b46c91827f05709L, 0xb65a18500f2eb1edL, + 0x139cfccdf9e9b314L, 0xfb1530b67f7b2d85L, + 0x30af529e584cf698L, 0xd033855a53e583f8L, + 0x8e31719cd6cdf570L, 0x22523048d0da2377L, + 0x3e8044069d97852bL, 0x3c39d2cbcd1b2c1dL, + 0x2d2adcf519e1a008L, 0xadf70fc987d268f1L, + 0x266a202f5209cf6cL, 0x76d93d02702a3a41L, + 0xc0d96ee1038eb568L, 0x1d0879a27a64b570L, + 0x07a6a4203894a9d5L, 0x2e348a4fa8a898e9L, + 0x7620707b305e5359L, 0xa7189ea8ca418e22L, + 0x71ba865e08c65f39L, 0x10ea977a00639f58L, + 0x0f7232d044c905a7L, 0xe4dc4fe25643768eL, + 0x5677ae7043aeab2bL, 0x3e2668c30a2366c3L, + 0x68da9eb5cbd3acf4L, 0x7e403ab2db9bad9dL, + 0x10bf63ec44481cb0L, 0x4f280560d6d3170fL, + 0x31d84cab54bd834cL, 0x3b45fc7c636be753L, + 0xbc32b7eb7598f8d1L, 0xfbccbabcad5ff0f9L, + 0x645110b1293368d6L, 0xcd248351bbe2b24dL, + 0xa867e34ab27ec1f0L, 0x8d1fb04424c9baffL, + 0x45ce62dc280a3836L, 0x2fd896ee3991fd50L, + 0x752b9946bafe3590L, 0x804eb86e38bc33a0L, + 0x35a8ea771e356106L, 0x115832afdac2cdd0L, + 0x538e847723131f4cL, 0x3c675774ad4d6094L, + 0x32df439637c97fc0L, 0x5ca2626cea5c600fL, + 0xa77207dc69768921L, 0xc2da4c5bc58a5c02L, + 0x1a30ea8c757b802cL, 0x0dc340462a516352L, + 0x19ffae863b0047c9L, 0x2e52259eb0738d36L, + 0x4602f7a8e00f7c33L, 0xdcc8132e6b498d4eL, + 0x4d7ba1aea0b93259L, 0x6452d3ad6d77d8bbL, + 0x98b8cff51c89dd28L, 0xbddcb0fe98edaf23L, + 0x9bd073e703c2919bL, 0xefb28109355209dbL, + 0x961e9ac2489d9b60L, 0x81c32ad7d5dbc7caL, + 0x3fa059fc7f59bfc1L, 0xf9a5918eb5d82d35L, + 0x75812ea02d3e2b65L, 0xe9a2468a44411eecL, + }; + private static final long[] hashLong5 = new long[] { + 0x5bddb46c2a42569fL, 0xc48d3843fd689bffL, + 0xca637d5049d9bad1L, 0x5636fe39fccc38a5L, + 0x24bc023ff30cbc01L, 0xcbfb460cee8ccb4eL, + 0xfb7dab6b09af9e25L, 0xe07c240ce73f41c9L, + 0x7a890ba50e5c1d62L, 0x0150f65610dcdb4aL, + 0x077de8d55224d186L, 0x84aed96ee3e363a6L, + 0x9e3c701b01140118L, 0xd75257b848593834L, + 0x87f50b46b74ae608L, 0x6c6b5f16a79e8d22L, + 0xf09f9ad05f2cdd19L, 0x59dab106ed7e89a3L, + 0x7e6942062854af6cL, 0xd00d9b18f4b2ab7aL, + 0x48b8ed323f438213L, 0xb1541a4dc1b1b330L, + 0xd7069ac9e65f32d8L, 0xf23cfa854fc17847L, + 0x2f9cb05b4fb39553L, 0x944a1b6cdb6ee75aL, + 0x9dc5d255d881ba03L, 0xd0ae22c66ed5f515L, + 0x94442efa655166f9L, 0x83a51881ad1ff91aL, + 0x9435a89a0f3c9887L, 0x19ff6ec641fec1aaL, + 0x1754f14e8f24d484L, 0x0e633f891cd42944L, + 0xc6acf9e343c20f81L, 0xbd3fca44ae31553aL, + 0x4bd370136c0ef039L, 0x9cf71fd6a25cbc3fL, + 0x7cf8cd663178f783L, 0x1965059e29fc1529L, + 0x7952f6f3983e01d5L, 0xb7f416b81f35e092L, + 0xf10180ce4342be14L, 0x8ae53164dcf68dbfL, + 0x6b713a265e138ca5L, 0xc8b6b40feb9158d1L, + 0xfaa1376c9c45445eL, 0xc663ed5d0d4c7345L, + 0x5a5b2484e742063eL, 0xdec263ecd2d65171L, + 0x8151b8e3195e6f13L, 0x79db73c19f09dc85L, + 0x01a5c91bd03a9145L, 0xc4ea30394dbd48e5L, + 0x79df68be140db665L, 0x25d7f86f8275ae53L, + 0xef64e03f5769dc92L, 0x6e7f34438e837eb7L, + 0x25ea88d6cdd703a7L, 0x0085413c90ad1eddL, + 0xffbbc3ff3ab6ad62L, 0x44475c971b44452dL, + 0x919ddc254091c01eL, 0x25a33588d310ea2cL, + 0x27296b2e8c01be14L, 0xbec7608cb6802f71L, + 0x823c0a9066f75b75L, 0x39bec7bf1d7fb2caL, + 0x0aeae9d62feb1ef8L, 0xf1ef2980e709aad7L, + 0xe718c3d4923ae8aaL, 0x6af278badae04722L, + 0xb80a8df6cac95f26L, 0xcfd70e48d6657d15L, + 0x5d01371656c7bdadL, 0x3c0abbc7add6679dL, + 0x8bde5a040d598278L, 0x6b669be9c09ff579L, + 0x90d39cc4b279cd21L, 0x239a4210b9215e71L, + 0x4488e0d2dbed504dL, 0x159c9033949075a2L, + 0x8d6d2b2482e0e296L, 0x0842f9b98671cb16L, + 0x703bc78298d1ea58L, 0x01981b247822bf55L, + 0xefec67ff020ad48aL, 0x3587a587bf2efadfL, + 0xdbf4f1d73854611eL, 0x89c8ac2421c05c67L, + 0x33b3938fa471a44aL, 0xf41e0f2f19c5107aL, + 0x990bde2a3fdc411cL, 0x8175676dece702a5L, + 0xcc8e15f052adb7abL, 0x0b1249d3de927906L, + 0x2ad2e8fa42229a3cL, 0x1fd4b8c73c0f1b2aL, + 0x23c4df42ca191a02L, 0xb71e90158f82078aL, + 0x4f5b8fa198a7640cL, 0x1b08531625843d91L, + 0x4d9e828280b9c525L, 0x85a5eb53b35f75cfL, + 0xc4160c325c2f3c43L, 0x2575f91e3324c4a5L, + 0xef3fd08d16cbff2eL, 0x77a1710590b78b65L, + 0x6618adfb212dbc15L, 0xadcd40fc37bc7985L, + 0x132aa68971f31791L, 0xf718b90c42f15681L, + 0x649a4ec612b13304L, 0x17ecda583233dbd3L, + 0x4bdf812bf0c3a922L, 0xc366fbee67f3760fL, + 0x2047a5f1a5f6448aL, 0x4f8327dd80bc522cL, + 0xb33cde09c85f0ddeL, 0x4f4818157f57ad76L, + 0xc0468903b5e61b33L, 0xc07b132e1ad26522L, + 0xae74dd8cb606aed3L, 0xc641668789519806L, + 0xcf4c8dbb7dbd2e99L, 0x36e492cc6928b3ccL, + 0xdc3b8581903e10f9L, 0x00b82a6371221f0bL, + 0x3dae8c5b2ba9cb21L, 0xc2e1adf2beca3459L, + 0xa9069e04dc1a6fd0L, 0xd6ffe724361d9ca9L, + 0xb0d87f8323ff6025L, 0x55aef677b1cefb0dL, + 0x91d955015be016f3L, 0xe59ff5202fb60ab3L, + 0xb6eab4c7fe6dc6e7L, 0xd247df66865d8a85L, + 0x7ef5bcc99dcd7b51L, 0xce9061bb3db68e3bL, + 0xf194bc1ce482bd61L, 0xe26ba0b0a74084e5L, + 0x132ca3945d59ab8dL, 0xf0ec4ad53d69ffceL, + 0x813e0eeed888de71L, 0x59cb04e39de6e428L, + 0x58e96aad65f2322dL, 0xc2ba7d58861bfd7aL, + 0x49db4ac8050b08d5L, 0x85eb22bbfd33d0dbL, + 0xd129d451d7157cd3L, 0x451afee5380f65f6L, + 0xdef9241bfa369164L, 0x2fe288476154b6d1L, + 0x645470b5a74128bbL, 0xf8623ba2b5230e5cL, + 0xf2e24605ff591525L, 0x17c50e43bbee40adL, + 0xc17f628e6add557fL, 0x371d778d777c9db4L, + 0x5565192ab19a824bL, 0xde1045562b071a7aL, + 0x8e0cc68dcc23b1deL, 0xce4b1289c17b6ce8L, + 0x12094c4372ffde5dL, 0xafe54750d55ccdcfL, + 0xf3bf23221bf52191L, 0x6f57c7f7baf8c9b7L, + 0x52fa1e36d43b1b28L, 0x08581282849ff846L, + 0x8c00144293f4c616L, 0x2098d83bc99f2066L, + 0xacf128cbd1d37cc8L, 0x68c7db0b01c829ccL, + 0xfef7a1f6e5495600L, 0xc2a48df6dfcbd89eL, + 0xe3a3de046cc11471L, 0x14937c52a0b7b728L, + 0x90e9b29145e919b9L, 0xa41b34c87568a764L, + 0x3c5f78fccb894a12L, 0x2ff6d49cb4b7e8ceL, + 0xcf5c41ee0fe373ceL, 0xc35a523ab2d469f7L, + 0xe92af43ada6303cbL, 0x64cc228cff31243eL, + 0x90d24b7d285898a8L, 0x28fc98c38feb496cL, + 0x70754e2ec1608bfaL, 0xfed007d7bd9e81aeL, + 0x549235d9dcbfc5cfL, 0x05ed096c0dc52b46L, + 0xa71dcbd2f3b61f41L, 0x1b57f7bade8e6efcL, + 0x53cc164f5a30b50fL, 0x37112a96af380be9L, + 0xa0970cb8168c3cf7L, 0xb5b0998ec76b52d1L, + 0x3394bce9068aef8cL, 0x179ea2590fdfca28L, + 0x9bf3215dabc41759L, 0xff48ae98813c2e1cL, + 0x7558255e80be0adaL, 0x8e0fffc2edb13861L, + 0x494fe88550bbd960L, 0xe0b41fa3f5f097a2L, + 0x64e6df8e4438344aL, 0xf7c6a66fc910d554L, + 0x4694d18c66b1c8f1L, 0x970d4bd7977d0044L, + 0x3ab6bd3d12006b71L, 0xee10d0460148c5beL, + 0xb46dbfa0bdae873fL, 0x4411dd91b42f4c93L, + 0x22ac4d19074499aeL, 0x00a6bad5fad388c2L, + 0xd13a2f7a88435396L, 0xdd4ac0123b59a5a7L, + 0x3184f4fdeae9c458L, 0x230c0e2d22e5ca0dL, + 0x603054d109cba5cdL, 0xcd14b952655211eeL, + 0x754e2fb1fb91dcb7L, 0xc892bb85207b662bL, + 0x7989cc8a05379679L, 0x026e3e9a2ccf1e0aL, + 0x31da9dd1c42427f7L, 0x56fc0e7370801546L, + 0xb130ac675564c9ccL, 0x4c3f556ee3f9ce5cL, + 0x8b80e3c57ad597fcL, 0xd992ffad3dedc578L, + 0x4626f3841db74d48L, 0x61e7c5a3782f4a03L, + 0xbec1dedbde8e22e7L, 0x2a798ce232fd84bcL, + 0xd6d4109e4e80b3a6L, 0x04196583c92241f0L, + 0xb96e362b86fd024dL, 0xe485d6a0acc50244L, + 0x30c4254bd461c206L, 0x068a4edd415b8fd6L, + 0x7684e3a27f5f34a1L, 0x59c491e531816f05L, + 0xbfd52ef73cc1dfd2L, 0x4df1a5cc10e84943L, + 0x481019e44f3b8be3L, 0x77af4e840bced822L, + 0x066aa0a9fa259b8fL, 0xffd7400c6fd2c95bL, + 0xf40a388d64f6e521L, 0xd373ccc4ba792f60L, + 0x656a843d478ae8daL, 0x3b1f231fe8f3d21dL, + 0xa9de43bf2e5e0b98L, 0xec03fea3370f4075L, + }; + private static final long[] hashLong6 = new long[] { + 0x2f1688dd9c4b1161L, 0x34522f58ea08a820L, + 0x399446bc586c89b9L, 0x07ff5757c91963a6L, + 0xf8f59ef8a91022eeL, 0xc0ce2196385ffdefL, + 0xf2a18cfa6022f7d1L, 0x1da1e243d012a87eL, + 0x8623a6c7b1fbd834L, 0xf6938459f886acabL, + 0xb5c3101859715fd5L, 0xa8a02735ba5c2f3cL, + 0x5f88234d4ebc584bL, 0xade87b06a1527cf9L, + 0xb6100c3960d9a9a8L, 0xc1beef560aade58cL, + 0x2350f799918d0aa5L, 0x9ce688ff41d96415L, + 0x2da49e9fd902c56bL, 0x6bb33e9d571effd8L, + 0xe230ab7f09668ec7L, 0x2de5148ccee0d09aL, + 0x2906fb37e4004e5eL, 0x1868a1775d0adbe9L, + 0x41d07ab0ac17141fL, 0x15abc4604422da86L, + 0xf2906befd725bfd6L, 0x4252a8c5b66f9fa6L, + 0xb2b9549feb799fc2L, 0x93967fbfc267d318L, + 0xbfbe292c599e01b1L, 0xe682f877218617b9L, + 0x690d35ac6d2e91b5L, 0x7e155b8a2095d54eL, + 0xefe0410fe131690dL, 0xdb51174ee244b5c1L, + 0x5795e11994ab430aL, 0x04a87e9724194c06L, + 0xe6ee83252c90facdL, 0xc905559f3c60f2deL, + 0xe1c4ae71a1669acaL, 0x621564f925cf8cc0L, + 0x7068804db4bcb208L, 0x460380657ac3adf3L, + 0x46fb829f097ebb5aL, 0x03275d2614c8687cL, + 0x7bb065c99406ad24L, 0xdc1a372cadca2c19L, + 0x680f443cd7022529L, 0x82a96691e79f9d88L, + 0xa797e887c34b4379L, 0x20057398863fbca8L, + 0xa0c652e640ffca37L, 0x71e3ea5288d49611L, + 0x307731b15cc18940L, 0xe3197e18a135abbfL, + 0x8b479caf9510fc4aL, 0x84e6edef54fcbed3L, + 0x6a5e0be5bb315951L, 0xecfcd8fef1f574cfL, + 0x3bd9d2ab8a979610L, 0xc3faaedaad04e491L, + 0x48b381160093ef05L, 0xf728c874bb3899f9L, + 0xe4058a85d402699dL, 0xca2c3ba2b594cf80L, + 0x736c3700cf3d20eeL, 0xffd6f00bc69d2803L, + 0x54d57f2a9fd0ce3eL, 0x62a977f3ada55e42L, + 0xec1ad7fafe00a76dL, 0x33778f97069f215dL, + 0x05195641fce81623L, 0x02a4bcd87a6b57fbL, + 0x62b7193f96788358L, 0x7efff2941a768347L, + 0xcba6738d47e71ae9L, 0x59887b73d32cb1beL, + 0x2d5d5f1165a3c6b9L, 0x2ef9aa9d69df6a86L, + 0x43bd68a5ffceb41eL, 0x913a81de5cd02673L, + 0xd61e870451117a5aL, 0xbee5107221c5cfa4L, + 0xf003fceae39016dcL, 0xc2665aaa097f4fbaL, + 0x3f46ef7a2fa6f47cL, 0x96a42e096ff1b66bL, + 0xa3560fc492a6d8f0L, 0xf3efabb64cf5d181L, + 0x261ba96558922a57L, 0x97bfe361eb94ff45L, + 0x252637a6e338837dL, 0x152a9b5fca6c4b9dL, + 0x7090f73f0dc6feadL, 0xc4f3fa5e3a76f1deL, + 0x3a494d8959f60b4dL, 0x3326fd8dce1c330cL, + 0xa9ea6cd2beadacf0L, 0xff32cae3bfbd3911L, + 0x315e5ef73eeabfa4L, 0xa98c230de1904e8aL, + 0x54c075940bc41d53L, 0x9cb0bc8d560eb966L, + 0x7fa9949886f5d9f0L, 0xbe270cee4c23a085L, + 0xb696d54811271e5eL, 0x445cee8b07720bbbL, + 0x9ca84eebda8a2350L, 0x1b24d46970e47bd8L, + 0xbe8d3fe84f58d141L, 0x1147ca37f7691eaaL, + 0x219416088244e330L, 0x89c4e308cca74823L, + 0x43c18ee132115e8aL, 0x3059e9619aa95912L, + 0xc08ca53633fab188L, 0x33c7957416c7f4dcL, + 0x09b25ee9d20b88acL, 0x958c837cfda6ff49L, + 0xb7bab9af4f61c68cL, 0xb0d06b590b707817L, + 0xc69b083db31fe9b2L, 0x57a90f1bff675b80L, + 0xba1e35a7bc8ccf5fL, 0x4cf9d4832ce1a3b4L, + 0xfb934a7fc1835018L, 0x29cbcfcf125cab6aL, + 0xca784927a1bee121L, 0xaf6fecc4ac466de5L, + 0x1dbbcee8c6be172dL, 0x7a59f224c0393333L, + 0x4d67f608a9672428L, 0x38deb365b1c30afaL, + 0x559c8067d9812322L, 0x0881ad78718e0597L, + 0xee9602cd5ddad461L, 0xdd48b446a323ce23L, + 0x352e3dc9d55a8327L, 0xffa00ad8eaa2fe88L, + 0x6bf961b3a28c6dd4L, 0x7542f612ac5fb433L, + 0xd87a29a04686f6e5L, 0x5e2348c936f49418L, + 0x5948c20130988ad1L, 0x70e3d800f71425e9L, + 0x17c3df8b03b5159aL, 0xc549b05f220b3ab3L, + 0x389419cf772cdff5L, 0x8124d52744a583d5L, + 0x57249a08b35202afL, 0x36b48f9df8b02df2L, + 0x22f04a1424caff80L, 0x9fce96893bd9ae72L, + 0xa7497b9b9853c8d7L, 0x73618d2190ee1e9aL, + 0x10a5b7fef9d30901L, 0xb86bb3bafe9437a3L, + 0x85bfe2c9b1beb5feL, 0x1bdcac6ab885a2b5L, + 0x71e329af37882e5eL, 0x33d6f8c0e519371fL, + 0xe801b0ffebf1d67eL, 0xd29778bc11e2cd70L, + 0x77b958f58c8842c5L, 0x0d27486bc6669c5bL, + 0x69942f6046818309L, 0x8294955c0abdd180L, + 0xa13e2416524db295L, 0xde0e4485e6b70a00L, + 0x01878b4ef9b8593aL, 0x5aa4a6af9d7c2d25L, + 0xc239837ef2ccf7a2L, 0x1f879d61c3f08b83L, + 0x04269f9181cc5a0fL, 0x5d8f4d9486858a20L, + 0x427d0117b7c69662L, 0xb73ad8319739942bL, + 0x481e1e0606717e91L, 0x7890ab9605122a22L, + 0xa434d6cc9d37537bL, 0xf8df029d54589ed5L, + 0xd6a9cd734ed73099L, 0xf11ed482bbd7bb06L, + 0xad62e0af8fd5343aL, 0xa3b21dc915f6e9afL, + 0xe973202e52a0c314L, 0x263e26ff1b2c8592L, + 0x9d1caa8890925e0eL, 0x8cff7e39f50ed11aL, + 0x75df89fdc4f061dfL, 0xbacae454e013cfc3L, + 0x583e6b1f026f3645L, 0xd30055d887915bb7L, + 0xa482ff78e4c34828L, 0xc01042679c2d22bcL, + 0xdd81fc2d1154ffdaL, 0x6f684ee4814e6f93L, + 0x99b2daf5a61a31daL, 0xc6003e52ba7ca41cL, + 0x475ebeba778cb084L, 0xaf56427f4e8a8ce2L, + 0x36a1102f9f1ce594L, 0xb4ffcb86bceff2faL, + 0xa9679ca263a01092L, 0xc9f05c3c01ca9a7bL, + 0x5178c73a7a7f3a78L, 0xedc700391b064c12L, + 0x78ab0870c919a2d6L, 0x68d2e365b6ffb1c1L, + 0xcc57a564b75c8557L, 0xfd3a4e47fc40dfc6L, + 0xee798d90a53a24deL, 0x0f06732d072de81bL, + 0xdf75c3e899f78330L, 0xcb1f8c5243f1b506L, + 0x97883048e7c81588L, 0x91abaa1727424ad7L, + 0x564cb648c56fa14cL, 0x4f75a6fd5603fe70L, + 0x646b51d7493e9bceL, 0x08260f9ca7ff3e28L, + 0xcade5c8ab530aaeaL, 0x18562db10194bee7L, + 0x2b2859dac461ba2dL, 0x5824176d2b1a0255L, + 0x32c4675f5e7862ceL, 0x889ca6d1b9c93673L, + 0xbf1d3bbb73842fbaL, 0x13f37037261a0246L, + 0xfc703c39e344f5c6L, 0xfbfb015901e5a305L, + 0x4987b48ff4fb31ddL, 0x8f377dad22d48456L, + 0xe3b1b57c7c77aa2dL, 0xea4de46dc4864f25L, + 0xe7a724d13c3be6b7L, 0xa695f4df8c953859L, + 0x47d93099ed7290b8L, 0x0ff90fb0b1996e9cL, + 0xd63254a370a62883L, 0xaeb58de7073328e2L, + 0xeb8968334bf782c8L, 0xc4b5676102584bafL, + 0x340c342a7e414b15L, 0x1c34eeb4c23f015fL, + 0x61ca4a4fd0583788L, 0x220a210dc76d0d95L, + 0x358043022fe60117L, 0x5f9cb5024e6b33eeL, + 0x6d2ccbd5a49aaf98L, 0xf22fabbef0702615L, + 0xc6809cf73a386552L, 0xf8650973b8c9ebb4L, + 0x26b0d8bdd5f9a214L, 0xef1918125436badeL, + }; + private static final long[] hashLong7 = new long[] { + 0x4fe30cdaea3300eaL, 0xd172e0db5b20eef1L, + 0x17e8d13e061e70a2L, 0xe6f9c96976183148L, + 0xdc93086d01c88189L, 0xebb7dc0f4536e89dL, + 0x25b1165405cd65ddL, 0xc7ed670cff2aa9ffL, + 0xde782850c0ae03d3L, 0x3606d2e5944738deL, + 0x0689643b4a7e9d65L, 0x2c3577167b22e02fL, + 0x822f825db3d46352L, 0x4ad9b33482bb5916L, + 0xab0837e37086bef6L, 0x0aa33175440f0ea9L, + 0xd51cc5639b624a6cL, 0xdad32be0163af89dL, + 0xabf93c543a6b1203L, 0xc71e93be1dba6dd9L, + 0xa77b0ff8cf1c0522L, 0xfd77133ef5d41722L, + 0x3a8d9ba0d7960374L, 0xb14ca5e9a2e2be60L, + 0x1d624b8553b32a07L, 0xaf8f34e537e2d693L, + 0xcad05b7f666589f0L, 0x157ddffb881e9c58L, + 0x16d831379ed1e75bL, 0xeabc5077ad06c0a3L, + 0x031baff39e67f804L, 0x218d4e55b80db742L, + 0x801066c069043785L, 0x553a77c3280fb597L, + 0x678454824ad89f0eL, 0x26324e9180a786d8L, + 0x6e25da1aa5051148L, 0x03eb9846a0e1e69eL, + 0x64065d4f4f6d4223L, 0x502a6a36cd87c03dL, + 0x229ae94551729116L, 0xea8cb0e1e035275fL, + 0xdd216e388fc1c9a4L, 0x1b35cf079e9941c7L, + 0x63326d29371f6243L, 0x534e38e9baa1bedfL, + 0x2207971815bd159dL, 0xb4594d1c6ad8ce9fL, + 0xd505eba163757027L, 0x20fba452bc349f15L, + 0x9acde3ce9e6d0adeL, 0x67493e631815df15L, + 0x5aeb2d30cbff7800L, 0xcc08c9539fd1537dL, + 0x68a6b109412701faL, 0x109858715faf6afbL, + 0x204658aef1168148L, 0x1a35edd719269737L, + 0x4b41cd09de8eb0b9L, 0x6b1d6127a882b502L, + 0x5c8c012b10a39e96L, 0x2779fae8eab95324L, + 0xe68b8a773c081651L, 0x323c35f4e4386032L, + 0xadbe37e62d253257L, 0x5306da5435b3fd00L, + 0x3949461096697a73L, 0x67895053559ab899L, + 0x55d20f1a0651a017L, 0x4483284dda546bc3L, + 0x02763859c50529a8L, 0x2933cd950765c1f8L, + 0xeb39a90505bafef3L, 0x039053bc4e86d0b5L, + 0xdbe81bfa4866a6eeL, 0xbde9284c7ad1a31bL, + 0x1c316b76e8f82f54L, 0x5bddff4aa98f421cL, + 0x4491648764eaa1a0L, 0xf057b84d028a9545L, + 0x91332fba9eeef25bL, 0x906525b706ba5dd5L, + 0xa8ee032b125b6bbeL, 0x738e84d98b33d703L, + 0x3e54bbc2df347b83L, 0x58005e9ff0b7fad4L, + 0x6f535bdfdd0dca50L, 0xe4cb4b8fd0c7f33dL, + 0x82df7f0d287c5887L, 0x5bc13636ed507b94L, + 0xd0b92755863efc00L, 0xc743a616d62fce7aL, + 0xe0ad57b1e5ecaef9L, 0x786bc850295fd06cL, + 0x674a45de2316d6acL, 0x36db1da0ef242762L, + 0x3c51cc84ebd6d5cdL, 0xcd1aa348b7248363L, + 0xca8f8f3fe5714032L, 0xbe4705a762d8c367L, + 0x46294a41c7713857L, 0xf183b1a322ad1c3fL, + 0x0d7c2708eb88a10bL, 0xb876dcb2cb9264e6L, + 0xa4e3c0b18c82f3acL, 0x800f516ea537118bL, + 0x94a634ecda042ebbL, 0x169428859000db30L, + 0xbb1b25652a9fdfb2L, 0x46995969b20ef2a3L, + 0x9705b06fa4af31f5L, 0x4d6e4d55cf8e545fL, + 0xe2233859b0e47711L, 0x746968b8570b7e66L, + 0xa8685435ff90a10fL, 0x4eacf35a402e4efaL, + 0xf7da3128dfb7208eL, 0xe8b03864353b58d5L, + 0xdd181c257487f73cL, 0x0d7db57abf4894a2L, + 0x5fe6ef84ace2f56dL, 0xaae0dd05ebccb701L, + 0x4612ab202eef2ae2L, 0xd24d5d11a7982423L, + 0xa1352acc4033953bL, 0xac0a55af422883c6L, + 0x600a99ffda141620L, 0xc64c66a7a9a5e37aL, + 0x967cc44fd88b4993L, 0x190e87c6f3d3d446L, + 0xea94a3b9f50d57e6L, 0xee98a821839f99e6L, + 0x01d87353758e0295L, 0x952b338980ca998cL, + 0x096a968692e13e9dL, 0x943d8a141090efa8L, + 0x050d771f3fffa6a7L, 0x33f4930d2db29dd4L, + 0x1c9a1f837f25be01L, 0x80816c6c969bf49aL, + 0x2f1633665ce91e26L, 0x7c9d8cc3f2fe0cadL, + 0xc5b709f68150c465L, 0x363fcc088fdb049cL, + 0x0cea46526d20b956L, 0x12b28fbe38522477L, + 0x1a2f687c20fde73fL, 0xf490cb06a8b2a77eL, + 0x282a1c3bcfdc8b19L, 0x18ae5e3214ad7376L, + 0x9a97e62da915d204L, 0xdf919fc9b77ff005L, + 0x285762b3b2da985eL, 0x6110229098e59084L, + 0xb4081cb403c17aceL, 0xe50a54622542e5faL, + 0x93eb30c6c5ee6255L, 0x8f054207be11639fL, + 0xc3f68b87213812d8L, 0xe21e78a062f25d9dL, + 0x8bb906bc15687a92L, 0x5bc8b35bca7c146eL, + 0xb8520b4bec838dbfL, 0x3ae8642b6f183fa0L, + 0x90bd6ce6d854af23L, 0x9f83a538c912c4c0L, + 0x17d869728b6404b8L, 0xd050191c3c3da8ebL, + 0x963810decf8ad2baL, 0x313b52ef3edeb868L, + 0x45bd04ac8daa20b8L, 0x125e17d83d55ff46L, + 0xc9900d0cfa258d5dL, 0xc7ff6a2171fded4eL, + 0xc504feee24991c1eL, 0x936b1d9bb0e8e6abL, + 0x46d2320954a86fc2L, 0x7330d293d560fdc2L, + 0xb1ebe6a2c3d8adb4L, 0xde1497bd81672670L, + 0x2ba7fd3b7c322494L, 0x9ffbc1025926406bL, + 0x8caa6cdd9604cbc9L, 0x8a5aa525233c2849L, + 0x8a305e1b467f9b9eL, 0xc4fd243f8fe2baeaL, + 0x56600550d6ed0fc2L, 0xbc5393072f5e9c7cL, + 0xbcac0f17662dc3e4L, 0xafe2574b7b2e5cafL, + 0x4e952c6b060d259bL, 0x2f5bd924ce137be3L, + 0xad948bc65e057652L, 0xcd89017e4c161dd2L, + 0x8d2377f5df2ac750L, 0x59a646571ceedc66L, + 0xb97ce01aca6604b7L, 0x98b68d1397cc146aL, + 0xd269481adacc4ff5L, 0x7a9998d6338d5e5aL, + 0xec3377ad05bb0b13L, 0xeed388e5263a1aa1L, + 0xa5309054cf21c15aL, 0x3c7f0c769857b9c9L, + 0x4cb996c76e2ebf9bL, 0xa32bcc166a20e676L, + 0xbc5bee7b428dcf34L, 0x140a2120d74f4e0fL, + 0x38e705547c9c47bcL, 0x7f04e4389d9b11e6L, + 0x9f5c89b6d7d47aa0L, 0x950467ec030b8a7bL, + 0xc1b0a2e386d82162L, 0xe5d9df563ac0a91dL, + 0xb287124af275e2d7L, 0xeeae4363a625f80cL, + 0x836155da910f7e9aL, 0xc87b0078dc9007dcL, + 0x1dfd5bd2f3b36d63L, 0x51f52bbe127ed3a4L, + 0x617a67e296f6f341L, 0x1ad860db066f4182L, + 0x6d16488e53014885L, 0x72404d4f876903dcL, + 0x5ad42682d13ef683L, 0x897dda7420b1fb3bL, + 0x6a378b47805e2a14L, 0xb9178e8865f3096aL, + 0xfd9edc9e5a0976d6L, 0x9ac1530045fe3417L, + 0x4b772c22d2ca28a1L, 0x91ae9f45ec762543L, + 0xee5ff5036e520721L, 0x56bd20f8680e2779L, + 0x6574c12f4e6d0683L, 0x7704a8923480ea96L, + 0xf8e865529eeabb2dL, 0x79302f2961ac9b11L, + 0x4111e788fdb9badfL, 0x1cc7458ffbd341b9L, + 0x22edf6f4c457390dL, 0x9303bac2089c3048L, + 0xad5c1ed650b41219L, 0xe92e42fe2bdfbedaL, + 0x5e8b19ff21acc699L, 0xc0f6b2bbea88c9d1L, + 0x3fe9e7942bdee2d5L, 0xbb7ee65dea178cc4L, + 0x09637cd497daa365L, 0xe7f9c3d54b06bd59L, + 0x4ec0c2bea720b5e0L, 0x05f560ce7029bbeeL, + 0x1fb95a1e77f67a35L, 0xbb4133df6f3bee27L, + 0x67b6cca524f3b17aL, 0x04667bd4791126acL, + }; + private static final long[] hashLong8 = new long[] { + 0x0c3250761df340bdL, 0xb3c880a39138a674L, + 0xc507401af2b1aeb1L, 0x2dab086136263198L, + 0xd13c6a1bd2d7ec4bL, 0xaf7707f02507df99L, + 0x29413b5c4fe464adL, 0x528b37e79bd55a2aL, + 0x1fcafd47eddfefe0L, 0xb1d118d30b6a5f70L, + 0xdcafd09ad803fc2cL, 0xb23df5467e693959L, + 0xa9b5588cdd7c4b01L, 0xba9e9a420c272998L, + 0xa88cf35f0733e6bbL, 0xa4dd3da4cbf01f1cL, + 0x7744c454f260e804L, 0x2b29d73aa22fec78L, + 0x764b8c394c5c73e3L, 0xebd07663d00e3600L, + 0xfc04acf26a5932e5L, 0x240e35177f336705L, + 0xa2da34fba16d6837L, 0xc383ed7ca60f87c5L, + 0xb1347fa9a74ba755L, 0x61a8ba91aa3155c0L, + 0xeb7943eb5e5f2770L, 0x84853faaabc048bdL, + 0xe57ddd2dcdd416e8L, 0x2359839c473d5eb2L, + 0x26bcf421a0534f15L, 0xd72dd08f09eee9d0L, + 0xd5e90f5e60ffa53dL, 0xeb67a39c1f0ad624L, + 0xaad5d797e5ec18f1L, 0x1dc9d24f635d6afdL, + 0xf8135163631a69edL, 0x65a76306229a9782L, + 0x97f9835f5c68798eL, 0x1f0eb5992d78fef8L, + 0x25d7bf7f224609b2L, 0x292fcd5f3cfe0f60L, + 0x6864f2a5b44ebb3cL, 0xf8404a36cdd7fdd8L, + 0x526acad579ec6cbeL, 0xa30e0b8cad8256e9L, + 0x1c3a098634197dfeL, 0x257ff443584df9b5L, + 0x44d45b5d5436e8c8L, 0x0564d94f9ff90dddL, + 0x218bf0157fd76548L, 0x960a2c7c38987114L, + 0x9aaa957fca627fa3L, 0x75bf233e78664575L, + 0x94a2b1098c413fe7L, 0x604e881749b10bc7L, + 0x7c75c832ad10e1eeL, 0x3065a6ea0b262a1aL, + 0x7f0245cd8ca1e531L, 0x71b75a4e404f119eL, + 0x66e7718745266668L, 0xd1137394385f3ff9L, + 0x875637c73fc3b245L, 0x33e7712c06bb84a6L, + 0x83f0390074e13438L, 0x85895245b6112d94L, + 0x5f1c44af833139d3L, 0xcc78fbdee3176556L, + 0x9a7bdd83bf5de6d1L, 0xeec4a7dda1b715d1L, + 0x722fdb5f87d4b7a6L, 0x8a9dc9d08e96ce22L, + 0x8b5d703f73ce59cdL, 0xcd62a36036e444b7L, + 0x54a8b8491e3f8e7dL, 0x58daac3d558d1c08L, + 0x23aac5cb23a73456L, 0xdaf232764ecb1927L, + 0x8eefa86faa412c6dL, 0x41fe19df24ff6172L, + 0xf33f537234e09292L, 0xc108f69f7964e0e7L, + 0xe6dda50fa959a960L, 0x96fa6e7bd93a1fe3L, + 0x44d4f5af28ec4cf7L, 0x9006312550f6a6d0L, + 0x094760545819ae8eL, 0x2b83a77833ccbd70L, + 0xb3095533b1a7a51dL, 0xf824410cdc86cc8fL, + 0xa8d0870b00b22e84L, 0x8e80d5e0e3b26c17L, + 0x997d10def5d09889L, 0xa5d699ba199199eaL, + 0xe312e9ab3462a455L, 0x227dda89c57aa116L, + 0x76eecd48764b6ad8L, 0xe62f508bf2b7a5c9L, + 0x588678231868b604L, 0x8289696bb70ce2ebL, + 0xcdf70f222bde5b89L, 0x1fa4f45c08917068L, + 0xecbafde858bdf1f4L, 0x412238d90c2fa67eL, + 0x8b8bbf73a1768ba7L, 0x51a1810a93ad2653L, + 0xfbff11dcbb5ca52dL, 0xd6813b51680b0345L, + 0x91696ba9f51d1bacL, 0xa8d4fe2ab87fc2ffL, + 0x903909d3a7f95038L, 0xd04d10a8cce321e9L, + 0x5d2a3a27b103da4fL, 0x1eb03b78087451afL, + 0x0c0cef0e10ccd2a1L, 0x669c7f3d73eb8c7aL, + 0x253c4467c2659334L, 0xca8af4ba2b23314fL, + 0x9c397bd31d4cfcc5L, 0x3290baca1a12bcc1L, + 0xc19267683038b040L, 0x977542ed2d0e80abL, + 0x06eb1aeb676de243L, 0x79654f3cd1795acdL, + 0x487b286b8f9f2e30L, 0x69f6cbc170de282eL, + 0x257bdefa79a3feb4L, 0x66ee1b2805e75390L, + 0xb95161f98c03f59fL, 0x78cf7a5f3d3d8a90L, + 0x1226331858d74615L, 0xfac718ac2716ba01L, + 0x4ff36062a2e4f1e1L, 0xc27ee10efaaf1d3bL, + 0xc9fe267d675c7209L, 0x60a00ca6130fd48aL, + 0x11fde3d032a72b70L, 0x5d3cf6927d2780a6L, + 0x78937557af9240acL, 0xa387c59284dbd372L, + 0xdde01afeb99066bbL, 0x6c8d8f947d9ece05L, + 0x99651c4bcec24c6bL, 0xa53ea342121c6527L, + 0x26ff7f9f2168011bL, 0xaa8d2a20dd57e1b2L, + 0xf590e9e4d0f24536L, 0x2ca65ca0ed337af2L, + 0x106ad4eb1e31be8dL, 0x6beb39e275860e95L, + 0x4c4c53c1a6c2643cL, 0x36a3c4c8019d21c9L, + 0xad0c51246b92b881L, 0xa5455354cb72d698L, + 0x43756f6888f6f58aL, 0x073cc2d540aa24cfL, + 0x2534f4101d26b745L, 0xf4cb29504ed48229L, + 0xb38cc060e701b9f4L, 0xbbbb37b28d3545e4L, + 0xcd261a7de92f08b3L, 0x75da4190f3c66dc0L, + 0x7af04bbc66957aabL, 0xaed0976f2ca68e9bL, + 0x9e64b15fd4c7a8c6L, 0x02d614ccba69809dL, + 0x816da13c4a8a34aaL, 0x1b386bee4f609440L, + 0x79ef835f85006af7L, 0xa4252ad70513ab9eL, + 0x54a4dedfbf73445fL, 0x0310f985738ba98dL, + 0x4982fc467846e0a9L, 0x5defb9dc7ccf7f3bL, + 0xbf56491be1350f32L, 0x06e1e060ad94cbf2L, + 0x058025079d4bb9a1L, 0x34a8fbed8a43a852L, + 0x50c01deea6e02ce5L, 0x5b68a4c35d9a36d2L, + 0xc1a3dc43b9ebdb1fL, 0x84624ce4377a8264L, + 0xb0c85247790af160L, 0x6f2600d6059a0c0cL, + 0xbd4ee79e03deb21fL, 0x2c1ef9dc5bb4a2e3L, + 0x818dd5fe50e9e877L, 0x9efa957e0c7cca67L, + 0xa1c84a2cc2312925L, 0xaf0d8cd68e91749cL, + 0xc8ef1aebf14aa57cL, 0xe7f12d8ec07c8283L, + 0x12ce744fb281ce92L, 0x046f0f8b3fc14e1cL, + 0x7a60f39afdb470bbL, 0x94f841d81bb4ec15L, + 0x11523a9d368f2bcfL, 0xb6be1b7bdb44d08eL, + 0x702462c7c1521715L, 0xaa0df0be91b82511L, + 0x323b3f43e699560dL, 0xaa0b5d91e2650a82L, + 0xc30064e1114891adL, 0x6ae0a942b0e0f541L, + 0x117b2b3f038aec1dL, 0x88b8ed29ee15e020L, + 0xbc0db030f90d7a70L, 0x4220ecf4e1e7aa14L, + 0x9e3dd629261d843fL, 0xb0d5ae67cb8477ccL, + 0x3a1f6f073d0b93b9L, 0x88e8d1491f9a76d7L, + 0x64b252b28fdd5cb8L, 0xd614059cb7caa7adL, + 0x436a891d2d35f22eL, 0x6532576c9b3fbb56L, + 0xc5181602af9406cbL, 0x997a482aa6ef6e80L, + 0xccc04e0cd56ecfcbL, 0x639058bdf64d3f9aL, + 0xde2b9c955221f2aeL, 0x268c99051044096bL, + 0xdfe4b0ed16eb3f17L, 0x7463187c16bfbd57L, + 0x485120c43d0cc1a3L, 0x9784e0fbf1454e4eL, + 0xcfbb56361c885d65L, 0x7dee409fe49db19cL, + 0x73b0a8a338d3b265L, 0x09925ff1643a22aeL, + 0x553471e4e708ddadL, 0x7817340bf4fba17fL, + 0x0a22c80431a88a6dL, 0x7915fdbbe2d15804L, + 0x66f6a128110c2534L, 0xba4a2b778ae3b03dL, + 0x9bd1b672dee16f9eL, 0xc80702e2365e53a7L, + 0xc349b3a9776c3128L, 0xdded614ed30f0f1eL, + 0xb973616e36c460fdL, 0x12cd8778b05a64e6L, + 0xc41e52c252c2edfbL, 0x760597748f306aa3L, + 0x2d3e456f05e0f82eL, 0x46ead2c0d6c3c9a7L, + 0xaaf6d453474dda67L, 0x15f3cd7efb7b479bL, + 0xcb21f0b8804663ecL, 0xe15eb56f8b3cddb4L, + 0x7eda432358e3c651L, 0x95485aa1e498776dL, + 0x153c9aafa1d4e1adL, 0xbb118f3a0b7799d3L, + 0x0e6f58a264d7f0b2L, 0x25f804fb3f672d55L, + }; + private static final long[] hashLong9 = new long[] { + 0xe4a94f39bf75cf35L, 0x3947df9fdaa273f4L, + 0xdaca4d94e09d4fb8L, 0xaaaf393c9fe9f4f7L, + 0x9e90a5772f8e715dL, 0xb73260ef55ca3514L, + 0xd11beeb3225e8827L, 0xe846cfc213615a50L, + 0x68a98dee0a03c565L, 0xe1c73161ac020cb0L, + 0xc3be8075f557211cL, 0x049fd5af0b80b226L, + 0x855bd93a4ccebac6L, 0xb31950fb0c63660aL, + 0x1355d6e4b07871eeL, 0xbe32abaf9b6c508bL, + 0x3b8e24d42a227de6L, 0x6d49bee7147cc516L, + 0xdd6bab7f965e5074L, 0x8418969ca00ac239L, + 0x880e628190b3042dL, 0xffb5428c24a24288L, + 0xec132f421d838f3dL, 0x33dca146783fcf8cL, + 0xa6745bf893e31d74L, 0x5d1eff47b8c2f2f2L, + 0x8cecddce28552fe4L, 0x56df64c1188a01e1L, + 0x308922c76653c72cL, 0x061a909de71404c3L, + 0x3ff6332be4ff5688L, 0x12b85f83a4158ca6L, + 0x96661f692cd1a975L, 0x9a7926a6ef7995d4L, + 0x2bd8078f551e3bb9L, 0x0abba7ebfad12e5dL, + 0x7f3a5ee2b7908c2aL, 0xfd6c07ce0811c3f4L, + 0xc8227434257d51e9L, 0x88f731a36a3f28aaL, + 0x626219540e3e4bfcL, 0xd93d54120c101831L, + 0xe0fac70dd17dd094L, 0x57bc49b6be1c7c97L, + 0x6519289739279b79L, 0xe9de045697be8ee7L, + 0xd3933dc37e86c0fbL, 0xb8ca7986aecd6842L, + 0xf6d019714411eb3fL, 0x96e04a49a154226bL, + 0xe10c2798972314f7L, 0x15d53053beda91b1L, + 0xfac1297689188294L, 0x17ca47c9870ca571L, + 0x561680ed921986c5L, 0xeae6f5e6f45daf4dL, + 0x1947e4cfe2f80c2cL, 0x666a443341cf13f7L, + 0xb0eb3476d1077cf9L, 0xd225b4c789358380L, + 0xa24febf97ae1ca50L, 0x388ff00bb1ed1251L, + 0xdc75ad50a8c5091cL, 0xe21ace9952a84fdaL, + 0x14940a7e3c21787cL, 0x8cbaed889977cd32L, + 0xc3aaa1157a76bdadL, 0xced09aff87f56ffdL, + 0x184f65b561f0b683L, 0x5fc6bbcbc384372eL, + 0x055332040f366eafL, 0x6f713f954e83c84eL, + 0x3bcfa623f392e9b7L, 0x217ff1de5c9e013fL, + 0xab3f2ce2c12c4461L, 0xd636ce248f3f17e7L, + 0x044d6d06ea0428c4L, 0x96b65e66e7a2b4aaL, + 0xf6fc520915a62e32L, 0x62f959805a578014L, + 0x3d0d8d14c50d313dL, 0xd403dd0ddfd6dc74L, + 0xf1cf6680b7f53a48L, 0xc59fea47ffc668c6L, + 0x6c5712fa55dbe8d7L, 0xd24668e903e4ad46L, + 0x01f00c8136fe8653L, 0xcd1cd45dd0c87e1fL, + 0xa3d35f84a39c8963L, 0xcc642bc073057043L, + 0x750c1fef9139bec9L, 0xcf79cd50ff695ae1L, + 0x85e6117f2234df32L, 0x86de6b90abc5594bL, + 0x510a4836723b974eL, 0xf261163a4b00c6c2L, + 0x98091c9f11eda897L, 0x2c5acdb0d9b31fe0L, + 0xe2d7f20cd66b4c72L, 0x71ab56b65b8c9c19L, + 0x2e7426dabe3aed54L, 0xc585019a4e40eb97L, + 0x09eb2fe3315e30e9L, 0x76c31c6917dbb9dfL, + 0x5d98d34443f8f334L, 0x8b3f7eadc3d07b0bL, + 0x1479a894b864c613L, 0x9516110d3347f967L, + 0xb40497f8361e6103L, 0xb9bb85662f6c3bfcL, + 0xb969d6d0d7b92373L, 0x83b9b8596e3f5b14L, + 0x887e239471a3bd51L, 0xea5ea3de7b0d51a3L, + 0x36a6fd821aa641a4L, 0xb39c8c6d49d6ccf2L, + 0x8f094eb124761045L, 0x5c4fc5fe8fff5b80L, + 0x664c537cf798212dL, 0xa29bc733d8346e8aL, + 0x5cfc40926324a491L, 0x984ce2b9a1170205L, + 0xef9a44d88ae1e55aL, 0xccdd4501dbfd9714L, + 0x664011154d8f3e69L, 0xb7727e15190fae9fL, + 0x308b14eba070e058L, 0xdba44f6ca3609919L, + 0x3cca4c93f4ad6ee8L, 0xe5c68024608eb6f5L, + 0x0519736f2917e8b4L, 0x11b9b834e5ba7edbL, + 0x061db9cc5ff067e7L, 0x29dc12a9754ae8e3L, + 0xaaa4b81e8ce4ee77L, 0xad5dda47d948fac0L, + 0xfb6f613709fb3ddfL, 0x2619c7e249c38fa7L, + 0x943bee622eb5f72bL, 0x25774922a876dd00L, + 0x6a2b978d36f1bc24L, 0x19491f663cb2d14fL, + 0x2e999ca87cc20f7aL, 0x785ebaa989fdd1fcL, + 0xbf27679538e4a94bL, 0x5e00b90f329a63f5L, + 0xf0c5ac6991948ad2L, 0x051c05b474b71e61L, + 0xe39ebd0f6926071cL, 0xef797c2020a7e185L, + 0xd315a1e2c240c286L, 0xe33efb620462d890L, + 0xb16f0fe56f108056L, 0xb48786c12a9984e5L, + 0x538b62dfafe33f8eL, 0xb971b20d9d52de72L, + 0x10ca4c4063d9b337L, 0xcaee4321387ee1ebL, + 0xf1f37c0ad68a58cdL, 0x9ed4317227da05c9L, + 0xc6cc223add88230bL, 0xefc4f7f2c2f4848eL, + 0x0b3b08543776180cL, 0x91d01b9a4fa5a045L, + 0x22f3d41c7f162f66L, 0xade0947f00480165L, + 0x0c438159573c1058L, 0x71d118b46dac0c56L, + 0x0d806e497e314016L, 0x39049ce84023511dL, + 0xa7ac8e1500997b1dL, 0x8c693db7ac62795dL, + 0x620bd443db5d6f7cL, 0xc2ae0b7a513c3cb1L, + 0xe8863164495fe701L, 0xac6cfadef1f22f13L, + 0x6873be272bcfcbb6L, 0x4974e4c15717cb81L, + 0x57809d03d3b3efc8L, 0xe00d588044c04974L, + 0x9a017c637306340aL, 0x04c4f713b54c8457L, + 0xe64b2e94fcff77d7L, 0x91bf42551191cb8cL, + 0x02d874b694f2bf90L, 0x0497ea659d613305L, + 0x7dde537919bee2efL, 0x0aa9056acaad4804L, + 0x69c2d5a692c7147fL, 0x826a4833f3d134c0L, + 0xf7de4b6cb91d8467L, 0x5439b1f8fbd99bd7L, + 0xa28d395c89579f8cL, 0xbe649d6edae193a2L, + 0x9199fa5263c38e4bL, 0xc9152e05123a92adL, + 0x1f2866558920bebfL, 0x62294c09206fb00dL, + 0x88b70ec3f3ebf91cL, 0xc5c4690760d48ee5L, + 0xc7d0be373189ed88L, 0x3a3513107e40e60eL, + 0x88f78f2bc2c515ccL, 0x1f997769078dff98L, + 0xad6b7c3fe0467cd5L, 0xb198035bce683292L, + 0x7a3742358a5c75beL, 0x12476c953611141cL, + 0x100ca5236a10f962L, 0x2d5028f763da737fL, + 0xafe1fe69e6d4146eL, 0xe1f8cefff86839b4L, + 0x19839a041b3850ecL, 0x879a8a3dbc3129e4L, + 0xc62ef23a474449c0L, 0x841941b1563e42deL, + 0xb482bf340a875f14L, 0x5df1a1d31737a0d7L, + 0x24f7c6463c7f1ad8L, 0x9b180235d481bb31L, + 0xce7a66ea8feea38dL, 0x9594b6f99cd6e5a3L, + 0x3bd28008926d118fL, 0xc5b0b3d1d4513547L, + 0xb9c54d52ce5371c9L, 0x5af7c13fe02e3843L, + 0x5e40edde48b4d07cL, 0xc48f8c4a13f05e3dL, + 0x48eac5b3fc7f85c6L, 0xd0b2b21de8e098b5L, + 0x8a4fae02ce12fa24L, 0x459c86675728d239L, + 0x8bc74cd3983783b4L, 0xded616c3ea7ae044L, + 0x5652bfdeeacb9ae7L, 0x9c38b299336d81deL, + 0xef5f3ed3e5df9074L, 0x0e3510c50ebef89fL, + 0x164f2b7dedf7a7d6L, 0xf315f6380bce534eL, + 0x6d9d96050510e826L, 0x341c0368f5c51199L, + 0x09f0852a77b20843L, 0x8c257a6d3c6ea476L, + 0x09bd288b933af0b7L, 0x7fa5b7a97d291bf1L, + 0x169419a7d1bb3b38L, 0xb3906714d76a9b2aL, + 0x6a65bd538aaa860cL, 0x4161ddff09ca83dfL, + 0x13bb9d8f011bb9f1L, 0x4f1f26246b61b79cL, + 0x6fe2d7fdb2ef00a7L, 0x04778fe99a50daafL, + 0xdf093796e5f3c1f3L, 0x6d5e5aee05ab302cL, + }; + + // hide implicit public default constructor + private IntegerHasher() { + } + + public static int hash (int n) { + return hashInt1[n&0xff] ^ hashInt2[(n>>8)&0xff] ^ hashInt3[(n>>16)&0xff] ^ hashInt4[(n>>24)&0xff]; + } + + public static long hashT (int n) { + long v = hashLong2[(n>>8)&0xff] ^ + hashLong3[(n>>16)&0xff] ^ + hashLong4[(n>>24)&0xff]; + return (v>>8) ^ hashLong1[(int) ((n ^ v)&0xff)]; + } + + public static long hash (long n) { + return hashLong1[(int) (n&0xff)] ^ + hashLong2[(int) ((n>>8)&0xff)] ^ + hashLong3[(int) ((n>>16)&0xff)] ^ + hashLong4[(int) ((n>>24)&0xff)] ^ + hashLong5[(int) ((n>>32)&0xff)] ^ + hashLong6[(int) ((n>>40)&0xff)] ^ + hashLong7[(int) ((n>>48)&0xff)] ^ + hashLong8[(int) ((n>>56)&0xff)]; + } + + public static long hashT (long n) { + long v = hashLong2[(int) ((n>>8)&0xff)] ^ + hashLong3[(int) ((n>>16)&0xff)] ^ + hashLong4[(int) ((n>>24)&0xff)] ^ + hashLong5[(int) ((n>>32)&0xff)] ^ + hashLong6[(int) ((n>>40)&0xff)] ^ + hashLong7[(int) ((n>>48)&0xff)] ^ + hashLong8[(int) ((n>>56)&0xff)]; + return (v>>8) ^ hashLong1[(int) ((n ^ v)&0xff)]; + } + + public static long hashT (int n1, byte n2) { + long v = hashLong2[n1&0xff] ^ + hashLong3[(n1>>8)&0xff] ^ + hashLong4[(n1>>16)&0xff] ^ + hashLong5[(n1>>24)&0xff]; + return (v>>8) ^ hashLong1[(int) ((n2 ^ v) & 0xff)]; + } + + public static long hashT (int n1, int n2) { + long v = hashLong2[(n1>>8)&0xff] ^ + hashLong3[(n1>>16)&0xff] ^ + hashLong4[(n1>>24)&0xff] ^ + hashLong5[n2&0xff] ^ + hashLong6[(n2>>8)&0xff] ^ + hashLong7[(n2>>16)&0xff] ^ + hashLong8[(n2>>24)&0xff]; + return (v>>8) ^ hashLong1[(int) ((n1 ^ v) & 0xff)]; + } + + public static long hashT (int n1, int n2, byte n3) { + long v = hashLong2[n1&0xff] ^ + hashLong3[(n1>>8)&0xff] ^ + hashLong4[(n1>>16)&0xff] ^ + hashLong5[(n1>>24)&0xff] ^ + hashLong6[n2&0xff] ^ + hashLong7[(n2>>8)&0xff] ^ + hashLong8[(n2>>16)&0xff] ^ + hashLong9[(n2>>24)&0xff]; + return (v>>8) ^ hashLong1[(int) ((n3 ^ v) & 0xff)]; + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/LittleMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/LittleMap.java new file mode 100644 index 0000000..c482c95 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/LittleMap.java @@ -0,0 +1,599 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.AbstractMap; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +@SuppressWarnings("unchecked") +public class LittleMap<K,V> implements Map<K,V> { + // A Map designed to perform well (space & time) for 1 or 2 items + // Doesn't support remove within entrySet or keySet + + private K key1 = null; + private V val1 = null; + // if key1 == null, then key2 is type HashTable, otherwise type K + private Object key2 = null; + private V val2 = null; + + private class LittleEntryIter implements Iterator<Map.Entry<K,V>> { + private int i; + + public LittleEntryIter() { + i = 0; + } + + @Override + public boolean hasNext() { + if (i==0) return (key1 != null); + if (i==1) return (key2 != null); + return false; + } + + @Override + public Map.Entry<K, V> next() { + i++; + if (i == 1) return new AbstractMap.SimpleEntry<K,V>(key1, val1); + else if (i == 2) return new AbstractMap.SimpleEntry<K,V>((K) key2, val2); + else throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + private class LittleEntrySet implements Set<Map.Entry<K,V>> { + @Override + public boolean add(Map.Entry<K, V> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends Map.Entry<K, V>> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + key1 = null; + val1 = null; + key2 = null; + val2 = null; + } + + @Override + public boolean contains(Object arg0) { + for (Map.Entry<K, V> e : this) { + if (e.equals(arg0)) return true; + } + return false; + } + + @Override + public boolean containsAll(Collection<?> arg0) { + for (Object o : arg0) { + if (!contains(o)) return false; + } + return true; + } + + @Override + public boolean isEmpty() { + return (key1 == null); + } + + @Override + public Iterator<Map.Entry<K, V>> iterator() { + return new LittleEntryIter(); + } + + @Override + public boolean remove(Object arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection<?> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection<?> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + if (key1 == null) return 0; + else if (key2 == null) return 1; + else return 2; + } + + @Override + public Object[] toArray() { + if (key1 == null) { + return new Object[0]; + } else if (key2 == null) { + Object[] arr = new Object[1]; + arr[0] = new AbstractMap.SimpleEntry<K,V>(key1, val1); + return arr; + } else { + Object[] arr = new Object[2]; + arr[0] = new AbstractMap.SimpleEntry<K,V>(key1, val1); + arr[1] = new AbstractMap.SimpleEntry<K,V>((K) key2, val2); + return arr; + } + } + + @Override + public <T> T[] toArray(T[] arg0) { + if (key1 == null) { + return (T[]) new Object[0]; + } else if (key2 == null) { + T[] arr = (T[]) new Object[1]; + arr[0] = (T) new AbstractMap.SimpleEntry<K,V>(key1, val1); + return arr; + } else { + T[] arr = (T[]) new Object[2]; + arr[0] = (T) new AbstractMap.SimpleEntry<K,V>(key1, val1); + arr[1] = (T) new AbstractMap.SimpleEntry<K,V>((K) key2, val2); + return arr; + } + } + } + + private class LittleKeyIter implements Iterator<K> { + private int i; + + public LittleKeyIter() { + i = 0; + } + + @Override + public boolean hasNext() { + if (i==0) return (key1 != null); + if (i==1) return (key2 != null); + return false; + } + + @Override + public K next() { + i++; + if (i == 1) return key1; + else if (i == 2) return (K) key2; + else throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + private class LittleKeySet implements Set<K> { + @Override + public boolean add(K arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends K> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + key1 = null; + val1 = null; + key2 = null; + val2 = null; + } + + @Override + public boolean contains(Object arg0) { + for (K key : this) { + if (key.equals(arg0)) return true; + } + return false; + } + + @Override + public boolean containsAll(Collection<?> arg0) { + for (Object o : arg0) { + if (!contains(o)) return false; + } + return true; + } + + @Override + public boolean isEmpty() { + return (key1 == null); + } + + @Override + public Iterator<K> iterator() { + return new LittleKeyIter(); + } + + @Override + public boolean remove(Object arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection<?> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection<?> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + if (key1 == null) return 0; + else if (key2 == null) return 1; + else return 2; + } + + @Override + public Object[] toArray() { + if (key1 == null) { + return new Object[0]; + } else if (key2 == null) { + Object[] arr = new Object[1]; + arr[0] = key1; + return arr; + } else { + Object[] arr = new Object[2]; + arr[0] = key1; + arr[1] = key2; + return arr; + } + } + + @Override + public <T> T[] toArray(T[] arg0) { + if (key1 == null) { + return (T[]) new Object[0]; + } else if (key2 == null) { + T[] arr = (T[]) new Object[1]; + arr[0] = (T) key1; + return arr; + } else { + T[] arr = (T[]) new Object[2]; + arr[0] = (T) key1; + arr[1] = (T) key2; + return arr; + } + } + } + + private class LittleValIter implements Iterator<V> { + private int i; + + public LittleValIter() { + i = 0; + } + + @Override + public boolean hasNext() { + if (i==0) return (key1 != null); + if (i==1) return (key2 != null); + return false; + } + + @Override + public V next() { + i++; + if (i == 1) return val1; + else if (i == 2) return val2; + else throw new NoSuchElementException(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + private class LittleValSet implements Collection<V> { + @Override + public boolean add(V arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends V> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + key1 = null; + val1 = null; + key2 = null; + val2 = null; + } + + @Override + public boolean contains(Object arg0) { + for (V val : this) { + if (val.equals(arg0)) return true; + } + return false; + } + + @Override + public boolean containsAll(Collection<?> arg0) { + for (Object o : arg0) { + if (!contains(o)) return false; + } + return true; + } + + @Override + public boolean isEmpty() { + return (key1 == null); + } + + @Override + public Iterator<V> iterator() { + return new LittleValIter(); + } + + @Override + public boolean remove(Object arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection<?> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection<?> arg0) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + if (key1 == null) return 0; + else if (key2 == null) return 1; + else return 2; + } + + @Override + public Object[] toArray() { + if (key1 == null) { + return new Object[0]; + } else if (key2 == null) { + Object[] arr = new Object[1]; + arr[0] = val1; + return arr; + } else { + Object[] arr = new Object[2]; + arr[0] = val1; + arr[1] = val2; + return arr; + } + } + + @Override + public <T> T[] toArray(T[] arg0) { + if (key1 == null) { + return (T[]) new Object[0]; + } else if (key2 == null) { + T[] arr = (T[]) new Object[1]; + arr[0] = (T) val1; + return arr; + } else { + T[] arr = (T[]) new Object[2]; + arr[0] = (T) val1; + arr[1] = (T) val2; + return arr; + } + } + } + + @Override + public Set<Map.Entry<K, V>> entrySet() { + if (key1 == null && key2 != null) { + return ((HashMap<K,V>) key2).entrySet(); + } else { + return new LittleEntrySet(); + } + } + + private HashMap<K,V> toHashMap () { + HashMap<K,V> map = new HashMap<K,V>(); + if (key1 != null) map.put(key1,val1); + if (key2 != null) map.put((K) key2, val2); + key1 = null; + val1 = null; + key2 = map; + val2 = null; + return map; + } + + @Override + public V put(K key, V value) { + if (key1 == null) { + if (key2 != null) { + return ((HashMap<K,V>) key2).put(key, value); + } else { + key1 = key; + val1 = value; + return null; + } + } else { + if (key1.equals(key)) { + V oldv = val1; + val1 = value; + return oldv; + } + if (key2 != null) { + if (key2.equals(key)) { + V oldv = val2; + val2 = value; + return oldv; + } else { + toHashMap().put(key, value); + return null; + } + } else { + key2 = key; + val2 = value; + return null; + } + } + } + + @Override + public void clear() { + key1 = null; + val1 = null; + key2 = null; + val2 = null; + } + + @Override + public boolean containsKey(Object key) { + if (key1 == null) { + if (key2 != null) { + return ((HashMap<K,V>) key2).containsKey(key); + } else { + return false; + } + } else { + if (key1.equals(key)) { + return true; + } + if (key2 != null && key2.equals(key)) { + return true; + } + return false; + } + } + + @Override + public boolean containsValue(Object value) { + if (key1 == null) { + if (key2 != null) { + return ((HashMap<K,V>) key2).containsValue(value); + } else { + return false; + } + } else { + if (val1.equals(value)) { + return true; + } + if (key2 != null && val2.equals(value)) { + return true; + } + return false; + } + } + + @Override + public V get(Object key) { + if (key1 == null) { + if (key2 != null) { + return ((HashMap<K,V>) key2).get(key); + } else { + return null; + } + } else { + if (key1.equals(key)) { + return val1; + } + if (key2 != null && key2.equals(key)) { + return val2; + } + return null; + } + } + + @Override + public boolean isEmpty() { + if (key1 == null && key2 != null) { + return ((HashMap<K,V>) key2).isEmpty(); + } + return (key1 == null); + } + + @Override + public Set<K> keySet() { + if (key1 == null && key2 != null) { + return ((HashMap<K,V>) key2).keySet(); + } else { + return new LittleKeySet(); + } + } + + @Override + public void putAll(Map<? extends K, ? extends V> m) { + if (key1 == null && key2 != null) { + ((HashMap<K,V>) key2).putAll(m); + } else { + if (m.size() + size() > 2) { + toHashMap().putAll(m); + } else { + for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) { + put(e.getKey(), e.getValue()); + } + } + } + } + + @Override + public V remove(Object key) { + return toHashMap().remove(key); + } + + @Override + public int size() { + if (key1 == null && key2 != null) { + return ((HashMap<K,V>) key2).size(); + } + if (key1 == null) return 0; + if (key2 == null) return 1; + return 2; + } + + @Override + public Collection<V> values() { + if (key1 == null && key2 != null) { + return ((HashMap<K,V>) key2).values(); + } + return new LittleValSet(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/ObjectFactory.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/ObjectFactory.java new file mode 100644 index 0000000..bbaaccf --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/ObjectFactory.java @@ -0,0 +1,26 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +public interface ObjectFactory<T> { + public T create(); +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/OrderedHashMapList.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/OrderedHashMapList.java new file mode 100644 index 0000000..77658d8 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/OrderedHashMapList.java @@ -0,0 +1,68 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Data structure for an mapping from <K>s to lists of <V>s. The data structure keeps track on the + * order new K was added and allow to retrive them in the that order. + * <p> + * Use the insert and delete operations. Do not use puts and remove. + * + * @param <K> Type of Keys + * @param <V> Type of Values + */ +public class OrderedHashMapList<K, V> extends HashMap<K,ArrayList<V>> { + private static final long serialVersionUID = 1L; + private ArrayList<K> list = new ArrayList<K>(); + public void insert(K key, V value) { + ArrayList<V> l = super.get(key); + if (l == null) { + l = new ArrayList<V>(); + super.put(key, l); + list.add(key); + } + l.add(value); + } + public ArrayList<V> delete(K key) { + list.remove(key); + return super.remove(key); + } +// public Object remove(K key) { +// throw new RuntimeException("USE DELETE"); +// } + @Override + public void clear() { + list.clear(); + super.clear(); + } + + /** + * @return the key set in the order they were first added. + */ + public List<K> orderedKeySet() { + return list; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/PersistedDateHashMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/PersistedDateHashMap.java new file mode 100644 index 0000000..4ae98ab --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/PersistedDateHashMap.java @@ -0,0 +1,112 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +import org.openecomp.ncomp.utils.SortUtil; +import org.openecomp.ncomp.webservice.utils.DateUtils; + +public class PersistedDateHashMap<K extends Serializable, V extends Serializable> { + private String filePrefix; + private HashMap<Date, PersistedHashMap<K, V>> map = new HashMap<Date, PersistedHashMap<K, V>>(); + private HashMap<Date, Boolean> uptodate = new HashMap<Date, Boolean>(); + private HashMap<Date, Date> createdTime = new HashMap<Date, Date>(); + + public PersistedDateHashMap(String filePrefix) { + super(); + this.filePrefix = filePrefix; + } + + public void save() { + for (Date d : map.keySet()) { + if (!uptodate.get(d)) { + map.get(d).save(); + uptodate.put(d, true); + } + } + Date now = new Date(); + List<Date> l = new ArrayList<Date>(); + for (Date d : map.keySet()) { + if (createdTime.get(d).getTime() + msInDay < now.getTime()) { + // created 1 day ago. remove from map to save memory + l.add(d); + } + } + for (Date d : l) { + map.remove(d); + uptodate.remove(d); + createdTime.remove(d); + } + } + + final long msInDay = DateUtils.stringToDuration("1day"); + + public void insert(Date d, K k, V v) { + getPmap(d).put(k, v); + setUpdate(d, false); + } + + public void remove(Date d, K k) { + getPmap(d).remove(k); + setUpdate(d, false); + } + + public V get(Date d, K k) { + return getPmap(d).get(k); + } + + private void setUpdate(Date d, boolean b) { + Date d1 = new Date(d.getTime() / msInDay * msInDay); + uptodate.put(d1, b); + } + + private PersistedHashMap<K, V> getPmap(Date d) { + Date d1 = new Date(d.getTime() / msInDay * msInDay); + PersistedHashMap<K, V> pMap = map.get(d1); + if (pMap == null) { + pMap = new PersistedHashMap<K, V>(dbFile(d1)); + map.put(d1, pMap); + uptodate.put(d1, false); + createdTime.put(d1, new Date()); + } + return pMap; + } + + private String dbFile(Date d) { + return DateUtils.toString(filePrefix + "-%Y_%m_%d", d); + } + + public void dump() { + for (Date d : SortUtil.sort(map.keySet())) { + System.out.println("Status for: " + d); + HashMap<K, V> m = map.get(d); + for (K k : m.keySet()) { + System.out.println(" " + k + " " + m.get(k)); + } + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/PersistedHashMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/PersistedHashMap.java new file mode 100644 index 0000000..0ccf713 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/PersistedHashMap.java @@ -0,0 +1,49 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.io.Serializable; +import java.util.HashMap; + +import org.openecomp.ncomp.webservice.utils.FileUtils; + +public class PersistedHashMap<K extends Serializable, V extends Serializable> extends HashMap<K, V> { + private static final long serialVersionUID = -1926264388357597164L; + private String file; + + @SuppressWarnings("unchecked") + public PersistedHashMap(String file) { + super(); + this.file = file; + HashMap<K, V> m = null; + try { + m = (HashMap<K, V>) FileUtils.file2object(file); + } catch (Exception e) { + } + if (m != null) + putAll(m); + } + public void save() { + FileUtils.object2file(this, file); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/SumMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/SumMap.java new file mode 100644 index 0000000..d1c7210 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/SumMap.java @@ -0,0 +1,44 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps; + +import java.util.HashMap; + +public class SumMap<K> extends HashMap<K,Double> { + private static final long serialVersionUID = 1L; + + public void increment(K key, double d) { + Double i = super.get(key); + double j; + if (i == null) { + super.put(key, 0.0); + j = 0.0; + } + else j = i; + put(key, j+d); + } + public Double get(Object key) { + Double d = super.get(key); + if (d == null) return 0d; + return d; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/tests/LittleMapTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/tests/LittleMapTest.java new file mode 100644 index 0000000..2ba19ed --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/tests/LittleMapTest.java @@ -0,0 +1,72 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps.tests; + +import java.util.Map; + +import org.openecomp.ncomp.utils.maps.LittleMap; + +import junit.framework.TestCase; +import junit.textui.TestRunner; + +public class LittleMapTest extends TestCase { + + public static void main(String[] args) { + TestRunner.run(LittleMapTest.class); + } + + public void testLittleMap() { + Map<String, String> m = new LittleMap<String, String>(); + assertSame("empty map size should be 0", m.size(), 0); + for (@SuppressWarnings("unused") Map.Entry<String, String> e : m.entrySet()) { + fail("map should be empty"); + } + if (m.containsKey("1")) { + fail("map should be empty"); + } + assertNull("1 shouldn't already exist in map", m.put("1", "v1")); + assertSame("map size should be 1", m.size(), 1); + for (Map.Entry<String, String> e : m.entrySet()) { + assertSame("entry key should be 1", e.getKey(), "1"); + assertSame("entry value should be v1", e.getValue(), "v1"); + } + assertTrue("m should contain 1", m.containsKey("1")); + assertSame("value of 1 should be v1", m.get("1"), "v1"); + assertSame("remove val should be v1", m.remove("1"), "v1"); + assertTrue("should be empty after removal", m.isEmpty()); + m.put("1", "v1"); + m.put("2", "v2"); + m.put("3", "v3"); + assertSame("value of put should be v2", m.put("2", "newv2"), "v2"); + assertSame("map size should be 3", m.size(), 3); + m.remove("1"); + m.remove("2"); + assertSame("map size should be 1", m.size(), 1); + m.put("2", "v2"); + m.put("1", "v1"); + m.put("4", "v4"); + m.put("5", "v5"); + m.put("6", "v6"); + assertSame("map size should be 6", m.size(), 6); + assertSame("value of 4 should be v4", m.get("4"), "v4"); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/tests/OrderedHashMapListTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/tests/OrderedHashMapListTest.java new file mode 100644 index 0000000..d502c30 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/maps/tests/OrderedHashMapListTest.java @@ -0,0 +1,49 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.maps.tests; + +import org.openecomp.ncomp.utils.maps.OrderedHashMapList; + +import junit.framework.TestCase; +import junit.textui.TestRunner; + +public class OrderedHashMapListTest extends TestCase { + + public static void main(String[] args) { + TestRunner.run(OrderedHashMapListTest.class); + } + + public void testOrderedHashMapList() { + OrderedHashMapList<String, String> m = new OrderedHashMapList<String, String>(); + m.insert("1", "v1"); + m.insert("2", "v2"); + m.insert("3", "v3"); + m.insert("2", "v2.0"); + m.delete("2"); + m.insert("1", "v1.0"); + for (String k : m.orderedKeySet()) { + System.out.println("key: " + k + " values: " + m.get(k)); + assertNotSame("2 should not be in the map", "2", k); + } + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/tests/FindFiles.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/tests/FindFiles.java new file mode 100644 index 0000000..b26430d --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/utils/tests/FindFiles.java @@ -0,0 +1,32 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.utils.tests; + +import junit.framework.TestCase; + +public class FindFiles extends TestCase { + + public void testFindFilesDateDateListOfString() { + fail("Not yet implemented"); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ByteBufferUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ByteBufferUtils.java new file mode 100644 index 0000000..fbb0550 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ByteBufferUtils.java @@ -0,0 +1,107 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.nio.ByteBuffer; +import java.util.Date; + +public class ByteBufferUtils { + + private static boolean debug = false; + + public static void getUnixDate(ByteBuffer buf, Date date, char c) { + date.setTime(1000*getLong(buf)); + } + public static void getUnixDateWithMilliSeconds(ByteBuffer buf, Date date, char c) { + date.setTime(1000*getLong(buf)); + getLong(buf); + if (debug ) System.out.println ( "getUnixDateWithMilliSeconds: " + date); + } + + public static int getInt(ByteBuffer buf) { + // TODO Auto-generated method stub + return (int) getLong(buf); + } + + public static long getLong(ByteBuffer buf) { + // TODO Auto-generated method stub + int i = 0; + byte c = buf.get(buf.position()); + if (c=='-') { + buf.get(); + return -getLong(buf); + } + for (c=buf.get();c>='0'&&c<='9';c=buf.get()) { + i = 10*i+c - '0'; + } +// if (debug ) System.out.println ( "getLong: " + i); + return i; + } + + public static void forward(ByteBuffer buf, char c) { + while (true) { + byte cc = buf.get(); + // if (debug ) System.out.println ( "forward cc c:" + cc + " " + (byte) c + " " + (char) cc); + if (cc == c) break; + } + } + + public static int getIpInt(ByteBuffer buf) { + int ip; + ip = getInt(buf); + ip = 256 * ip + getInt(buf); + ip = 256 * ip + getInt(buf); + ip = 256 * ip + getInt(buf); + if (debug ) System.out.println ( "getIpInt: " + IpUtils.toString(ip)); + return ip; + } + + public static StringBuffer getBuffer(ByteBuffer buf, char c) { + // TODO Auto-generated method stub + StringBuffer sbuf = new StringBuffer(); + while (true) { + byte cc = buf.get(); + // if (debug ) System.out.println ( "cc c:" + cc + " " + (byte) c + " " + (char) cc); + if (cc == c) break; + sbuf.append((char)cc); + } + if (debug ) System.out.println ( "getBuffer: " + sbuf); + return sbuf; + } + public static int mask2masklen(ByteBuffer buf) { + // 255.255.255.252 -> 30 + int len = 0; + for (int j = 0; j < 4; j++) { + int i = getInt(buf); + for (int x = 0; x < 8; x++) { + if ((i >> x) % 2 == 1) { + len += 8 - x; + break; + } + + } + } + return len; + } + + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DateUtilTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DateUtilTest.java new file mode 100644 index 0000000..47f9144 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DateUtilTest.java @@ -0,0 +1,107 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.text.ParseException; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import junit.framework.TestCase; + +public class DateUtilTest extends TestCase { + String fmt ="%Y-%m-%d %H:%M:%S"; + public void test_dateFromString() throws ParseException { + System.setProperty("user.timezone", "GMT"); + Date d = new Date(); + assertEquals( + "2001-01-01 00:00:00", + DateUtils.toString(fmt,DateUtils.dateFromString("01/01/2001")) + ); + assertEquals( + "2001-01-01 00:00:00", + DateUtils.toString(fmt,DateUtils.dateFromString("2001-01-01")) + ); + assertEquals("2001-01-01 02:02:02", + DateUtils.toString(fmt,DateUtils.dateFromString("2001-01-01T02:02:02.000")) + ); + assertEquals("2001-01-01 02:02:00", + DateUtils.toString(fmt,DateUtils.dateFromString("2001-01-01 02:02")) + ); + assertEquals(DateUtils.toString("%Y",d) + "-01-01 02:02:00", + DateUtils.toString(fmt,DateUtils.dateFromString("1/1 02:02")) + ); + assertEquals(DateUtils.toString("%Y",d) + "-01-01 00:00:00", + DateUtils.toString(fmt,DateUtils.dateFromString("1/1")) + ); + + Calendar cal = Calendar.getInstance(); + cal.setTime(d); + cal.add(Calendar.YEAR,-1); + assertEquals(DateUtils.toString("%Y",cal.getTime()) + "-12-31 23:59:00", + DateUtils.toString(fmt,DateUtils.dateFromString("12/31 23:59")) + ); + assertEquals(DateUtils.toString("%Y",cal.getTime()) + "-12-31 00:00:00", + DateUtils.toString(fmt,DateUtils.dateFromString("12/31")) + ); + + + Date oneHourAgo = new Date(d.getTime()-3600*1000); + assertEquals(DateUtils.toString(fmt,oneHourAgo), + DateUtils.toString(fmt,DateUtils.dateFromString("-1hour")) + ); + // these may fail for 2 minutes around midnight + Date midnight = new Date(d.getTime()/3600/24/1000*3600*24*1000); + Date minBeforeMidnight = new Date(midnight.getTime()-60*1000); + Date minAfterMidnight = new Date(midnight.getTime()+60*1000); + assertEquals(DateUtils.toString(fmt,minBeforeMidnight), + DateUtils.toString(fmt,DateUtils.dateFromString("23:59")) + ); + assertEquals(DateUtils.toString(fmt,minAfterMidnight), + DateUtils.toString(fmt,DateUtils.dateFromString("00:01")) + ); + + } + public void test_dateRange() { + System.setProperty("user.timezone", "GMT"); + Date d1 = DateUtils.dateFromString("2001-01-01 00:00"); + Date d2 = DateUtils.dateFromString("2001-01-01 02:00"); + Date d3 = DateUtils.dateFromString("2001-01-03 00:00"); + Date d4 = DateUtils.dateFromString("2001-01-01 01:00"); + assertEquals("2001-01-01 00:00:00",toStr(DateUtils.dateRange(d1, d1))); + assertEquals("2001-01-01 00:00:00",toStr(DateUtils.dateRange(d1, d2))); + assertEquals("2001-01-01 00:00:00",toStr(DateUtils.dateRange(d4, d2))); + assertEquals("",toStr(DateUtils.dateRange(d2, d4))); + assertEquals("2001-01-01 00:00:00, 2001-01-02 00:00:00",toStr(DateUtils.dateRange(d1, d3))); + assertEquals("2001-01-01 00:00:00, 2001-01-01 01:00:00",toStr(DateUtils.dateRange(d1, d2, 1000*3600))); + } + private String toStr(List<Date> l) { + StringBuffer b = new StringBuffer(); + boolean first = true; + for (Date d : l) { + if (first) first = false; + else b.append(", "); + b.append(DateUtils.toString(fmt,d)); + } + return b.toString(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DateUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DateUtils.java new file mode 100644 index 0000000..9b09887 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DateUtils.java @@ -0,0 +1,305 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.util.*; + +import javax.xml.datatype.*; + +import org.openecomp.ncomp.utils.FindFiles; +import org.openecomp.ncomp.utils.FindFiles.ParameterizedFile; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.text.ParseException; + +public class DateUtils { + private static DatatypeFactory factory; + static { + try { + factory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new RuntimeException("unable to configure datatype factory", e); + } + } + + public static Date toDate(XMLGregorianCalendar dateTime) { + if (dateTime == null) + return null; + if (dateTime.toGregorianCalendar() == null) + throw new RuntimeException("Unable to convert to Date: " + dateTime.toString()); + return dateTime.toGregorianCalendar().getTime(); + } + + public static XMLGregorianCalendar toDateTime(Date date) { + if (date == null) +// throw new RuntimeException("Date is null"); + return null; + GregorianCalendar c = new GregorianCalendar(); + c.setTime(date); + return factory.newXMLGregorianCalendar(c).normalize(); + } + + // @formatter:off turn off Eclipse formating. + private static DateFormat dfs[] = { + // since first matching format is used, the most specific need to be + // first + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z"), new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"), + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"), new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"), + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"), new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"), + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),new SimpleDateFormat("yyyy-MM-dd HH:mm"), + new SimpleDateFormat("MM/dd/yyyy"), new SimpleDateFormat("yyyy-MM-dd"), + new RelativeDateFormat("%dday", 24 * 3600 * 1000), new RelativeDateFormat("%dweek", 7 * 24 * 3600 * 1000), + new RelativeDateFormat("%dhour", 3600 * 1000), new RelativeDateFormat("%dmin", 60 * 1000), new FuzzyDateFormat() }; + + // @formatter:on + public static synchronized Date dateFromString(String str) { + Date d = null; + if ("now".equals(str)) return new Date(); + for (DateFormat df : dfs) { + try { + d = df.parse(str); + break; + } catch (ParseException e) { +// e.printStackTrace(); + } catch (RuntimeException e) { +// e.printStackTrace(); + } + } + if (d == null) + throw new RuntimeException("Unable to parse date from: " + str); + return d; + } + + // handle %H format strings + public static Date dateFromString(String str,String format) { + FindFiles f = new FindFiles("/"+format); + ParameterizedFile pf = f.fileMatch("/" + str); + return pf != null ? pf.getDate() : null; + } + + public static Object dateFromString(String string, Date relativeDate) { + throw new UnsupportedOperationException(); + } + + public static Date unix2date(String string) { + StringTokenizer st = new StringTokenizer(string, "."); + long l = Long.parseLong(st.nextToken()); + // System.out.println(string + " " + l); + return new Date(l * 1000); + } + + // sample format "yyyy_MM_dd'/outputs/'HH_mm_ss'.%U.gz'" + public static String gmtFormat(Date date, String format) { + DateFormat indfm = new SimpleDateFormat(format); + indfm.setTimeZone(TimeZone.getTimeZone("GMT")); + return indfm.format(date).replaceAll("%U", Long.toString(date.getTime() / 1000)); + } + + public static List<Date> dateRange(Date start, Date end, long intervalMilliSeconds) { + long d = start.getTime() / intervalMilliSeconds * intervalMilliSeconds; + List<Date> res = new ArrayList<Date>(); + if (end.before(start)) return res; + res.add(new Date(d)); + while (true) { + d += intervalMilliSeconds; + if (d >= end.getTime()) + break; + res.add(new Date(d)); + } + return res; + } + + public static List<Date> dateRange(Date d1, Date d2) { + return dateRange(d1,d2,1000*3600*24); + } + + public static long stringToDuration(String interval) { + Scanner scanner = new Scanner(interval); + Long res = null; + if (interval.contains("hour")) { + scanner.useDelimiter("h"); + res = scanner.nextLong() * 3600 * 1000; + } + if (interval.contains("min")) { + scanner.useDelimiter("m"); + res = scanner.nextLong() * 60 * 1000; + } + if (interval.contains("sec")) { + scanner.useDelimiter("s"); + res = scanner.nextLong() * 1000; + } + if (interval.contains("day")) { + scanner.useDelimiter("d"); + res = scanner.nextLong() * 3600 * 24 * 1000; + } + scanner.close(); + if (res == null) + throw new RuntimeException("bad format: " + interval); + return res; + } + + public static String toString(String format, Date time) { + format = format.replace("%S", String.format("%tS", time)); + format = format.replace("%M", String.format("%tM", time)); + format = format.replace("%H", String.format("%tH", time)); + format = format.replace("%Y", String.format("%tY", time)); + format = format.replace("%m", String.format("%tm", time)); + format = format.replace("%d", String.format("%td", time)); + format = format.replace("%y", String.format("%ty", time)); + format = format.replace("%k", String.format("%tk", time)); + format = format.replace("%U", String.format("%ts", time)); + format = format.replace("%s", String.format("%ts", time)); + format = format.replace("%L", String.format("%tL", time)); + return format; + } + + public static String delay2String(long delay1) { + if (delay1 < 0) { + return delay2String(-delay1) + " in the future"; + } + double delay = delay1/1000.0; + if (delay < 200) + return String.format("%.1f seconds", delay); + delay = delay/60; + if (delay < 60) + return String.format("%.1f minutes", delay); + delay = delay/60; + if (delay < 72) + return String.format("%.1f hours", delay); + delay = delay/24; + return String.format("%.1f days", delay); + } +} + +class FuzzyDateFormat extends DateFormat { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + return toAppendTo.append(DateUtils.toString("%H:%M", date)); + } + + @Override + public Date parse(String source, ParsePosition pos) { + String s = source.substring(pos.getIndex()); + Date d = null; + if (s.matches("\\d\\d:\\d\\d")) { + DateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + try { + Date now = new Date(); + d = f.parse(DateUtils.toString("%Y-%m-%d ",now)+s); + if (d.after(now)) { + d.setTime(d.getTime()-24*3600*1000); + } + pos.setIndex(source.length()); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (s.matches("\\d+/\\d+")) { + DateFormat f = new SimpleDateFormat("yyyy/MM/dd"); + try { + Date now = new Date(); + d = f.parse(DateUtils.toString("%Y/",now)+s); + if (d.after(now)) { + Calendar cal = Calendar.getInstance(); + cal.setTime(d); + cal.add(Calendar.YEAR,-1); + d = cal.getTime(); + } + pos.setIndex(source.length()); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (s.matches("\\d+/\\d+ \\d\\d:\\d\\d")) { + DateFormat f = new SimpleDateFormat("yyyy/MM/dd HH:mm"); + try { + Date now = new Date(); + d = f.parse(DateUtils.toString("%Y/",now)+s); + if (d.after(now)) { + Calendar cal = Calendar.getInstance(); + cal.setTime(d); + cal.add(Calendar.YEAR,-1); + d = cal.getTime(); + } + pos.setIndex(source.length()); + } catch (Exception e) { + e.printStackTrace(); + } + } + return d; + } + +} +class RelativeDateFormat extends DateFormat { + /** + * + */ + private static final long serialVersionUID = 1L; + private String format; + private long intervalMilliSeconds; + + RelativeDateFormat(String format, long intervalMilliSeconds) { + this.format = format; + this.intervalMilliSeconds = intervalMilliSeconds; + } + + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + Date now = new Date(); + int delay = (int) ((now.getTime() - date.getTime()) / intervalMilliSeconds); + toAppendTo.append(String.format(format, delay)); + return toAppendTo; + } + + @Override + public Date parse(String source, ParsePosition pos) { + String s = source.substring(pos.getIndex()); + if (format.startsWith("%d")) { + Scanner scanner = new Scanner(s); + scanner.useDelimiter(format.substring(2)); + if (!scanner.hasNextInt()) { + scanner.close(); + return null; + } + int i = scanner.nextInt(); + if (scanner.hasNext()) { + scanner.close(); + return null; + } + Date d = new Date(); + d.setTime(d.getTime() + i * intervalMilliSeconds); + pos.setIndex(source.length()); + scanner.close(); + return d; + } + return null; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DoOnce.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DoOnce.java new file mode 100644 index 0000000..1eacfe2 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DoOnce.java @@ -0,0 +1,45 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.util.HashSet; + +public class DoOnce { + private HashSet<String> doneMap = new HashSet<String>(); + public boolean done(String string) { + if (doneMap.contains(string)) return true; + doneMap.add(string); + return false; + } + public boolean done(Object o) { + return done(o.toString()); + } + public boolean first(Object o) { + return done(o) == false; + } + public boolean done(int i) { + return done(Integer.toString(i)); + } + public void clear() { + doneMap.clear(); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DoOnceArray.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DoOnceArray.java new file mode 100644 index 0000000..e8147f4 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/DoOnceArray.java @@ -0,0 +1,49 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.util.HashMap; + +public class DoOnceArray { + private HashMap<Object,DoOnce> map = new HashMap<Object,DoOnce>(); + public boolean done(Object o, String string) { + DoOnce d = map.get(o); + if (d == null) { + d = new DoOnce(); + map.put(o,d); + } + return d.done(string); + } + public boolean done(Object o,Object o2) { + return done(o,o2.toString()); + } + public boolean first(Object o,Object o2) { + return done(o,o2) == false; + } + public boolean done(Object o,int i) { + return done(o,Integer.toString(i)); + } + public void clear() { + map.clear(); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/EcoreUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/EcoreUtils.java new file mode 100644 index 0000000..6cc8f80 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/EcoreUtils.java @@ -0,0 +1,65 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; + + +public class EcoreUtils<T extends EObject> { + static String ecore2str(EObject e, int i, String[] delim) { + EStructuralFeature f = e.eClass().getEStructuralFeature(i); + return e.eGet(f).toString(); +// switch (f.getEType().getClassifierID()) { +// case EcorePackage.ESTRING: +// case EcorePackage.EINT: +// return e.eGet(f).toString(); +// } +// throw new RuntimeException("EcoreUtils::ecore2str: Unknow feature"); + + } + static String ecore2str(EObject e, int[] i, String delim[]) { + StringBuffer res = new StringBuffer(); + for (int j = 0; j<i.length ; j++) { + if (j>0) res.append(delim[0]); + res.append(ecore2str(e,i[j],delim)); + } + return res.toString(); + } + static String ecore2str(EObject e, int[][] i, String delim[]) { + throw new RuntimeException("TODO"); + } + public String ecorelist2str(EList<T> list) { + StringBuffer buf = new StringBuffer(); + boolean first = true; + for (T e : list) { + if (!first) { + buf.append(":"); + } + first = false; + buf.append(e.toString()); + } + return buf.toString(); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ErrorMap.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ErrorMap.java new file mode 100644 index 0000000..44d296e --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ErrorMap.java @@ -0,0 +1,83 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.HashMap; + +import org.openecomp.ncomp.utils.SortUtil; + +public class ErrorMap { + class Counter { + int c = 0; + } + + private HashMap<String, HashMap<String, Counter>> map = new HashMap<String, HashMap<String, Counter>>(); + + public void add(String catagory, String s) { + HashMap<String,Counter> cat = map.get(catagory); + int bound = 10; + if (cat == null) { + cat = new HashMap<String,Counter>(); + map.put(catagory,cat); + System.out.println("New error catagory: " + catagory); + } + Counter c = cat.get(s); + if (c == null) { + c = new Counter(); + cat.put(s,c); + if (cat.size() < bound) { + System.out.println("New error in catagory: " + catagory + " : " + s); + } + } + c.c++; + } + public void report() { + for (String cat : map.keySet()) { + System.out.println(cat + " " + map.get(cat).size() + " errors"); + } + } + public void save(String directory) { + File dir = new File(directory); + System.out.println("Saving errors in: " + directory); + dir.mkdirs(); + for (String cat : map.keySet()) { + OutputStreamWriter writer = FileUtils.filename2writer(directory+"/"+cat.replace(" ", "_")); + for (String s : SortUtil.sort(map.get(cat).keySet())) { + try { + writer.write(s +"," + map.get(cat).get(s).c + "\n"); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + try { + writer.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/FileUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/FileUtils.java new file mode 100644 index 0000000..423a1be --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/FileUtils.java @@ -0,0 +1,667 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.Diagnostician; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.eclipse.emf.ecore.xmi.util.XMLProcessor; + +public class FileUtils { + public static final Logger logger = Logger.getLogger("org.openecomp.ncomp.utils.io"); + static private ResourceSet resourceSet; + + static private ResourceSet createResourceSet() { + ResourceSet rs = new ResourceSetImpl(); + Resource.Factory binaryResourceFactory = new Resource.Factory() { + public Resource createResource(URI uri) { + return new org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl(uri); + } + }; + rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("dat", binaryResourceFactory); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("dgz", binaryResourceFactory); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("datzip", binaryResourceFactory); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl()); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmigz", new XMIResourceFactoryImpl()); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmizip", new XMIResourceFactoryImpl()); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put("xml", new org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl()); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put("xmlgz", new org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl()); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put("xmlzip", new org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl()); + rs.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl()); + return rs; + } + + static void init() { + if (resourceSet == null) { + resourceSet = createResourceSet(); + } + } + + static public void ecore2file(EPackage p, EObject ecore, String fileName) throws IOException { + ecore2file(ecore, fileName); + } + + static public void ecore2file(EObject ecore, String fileName) throws IOException { + if (ecore == null) { + logger.error("Trying to save null object"); + return; + } + init(); + Resource resource = resourceSet.createResource(URI.createURI(fileName)); + resource.getContents().add(ecore); + // error = validate(req,0); + // if (error != null) throw new Exception("Bad request"); + FileOutputStream fos = new FileOutputStream(FileUtils.safeFileName(fileName)); + Map<String, Object> options = new HashMap<String, Object>(); + // gz is misleading, but supported for backwards compatibility + if (fileName.endsWith("zip") || fileName.endsWith("gz")) { + options.put(XMLResource.OPTION_ZIP, Boolean.TRUE); + } + options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + try { + resource.save(fos, options); + } finally { + fos.close(); + } + } + + static public void ecores2file(EList<? extends EObject> ecores, String fileName) throws IOException { + init(); + Resource resource = resourceSet.createResource(URI.createURI(fileName)); + resource.getContents().addAll(ecores); + FileOutputStream fos = new FileOutputStream(FileUtils.safeFileName(fileName)); + Map<String, Object> options = new HashMap<String, Object>(); + // gz is misleading, but supported for backwards compatibility + if (fileName.endsWith("zip") || fileName.endsWith("gz")) { + options.put(XMLResource.OPTION_ZIP, Boolean.TRUE); + } + options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + try { + resource.save(fos, options); + } finally { + fos.close(); + } + } + + static public EObject file2ecore(EPackage p, String fileName) { + return file2ecore(fileName, true, true); + } + + static public EObject file2ecore(String fileName) { + return file2ecore(fileName, true, true); + } + + static public EObject file2ecore(EPackage p, String fileName, boolean unload) { + return file2ecore(fileName, unload, true); + } + + static public EObject file2ecore(String fileName, boolean unload) { + return file2ecore(fileName, unload, true); + } + + static public EObject file2ecore(EPackage p, String fileName, boolean unload, boolean useCommonRS) { + return file2ecore(fileName, unload, useCommonRS); + } + + static public EObject file2ecore_old(String fileName, boolean unload, boolean useCommonRS) { + File file = new File(FileUtils.safeFileName(fileName)); + if (!file.exists()) { + throw new RuntimeException("File does not exists: " + fileName); + } + // URI uri = URI.createFileURI(file.getAbsolutePath()); + URI uri = URI.createURI("file:///" + file.getAbsolutePath().replace("\\", "/")); + Resource resource; + logger.debug("Loading " + uri); + if (useCommonRS) { + init(); + synchronized (resourceSet) { + Boolean oldzip = (Boolean) resourceSet.getLoadOptions().get(XMLResource.OPTION_ZIP); + // gz is misleading, but supported for backwards compatibility + if (fileName.endsWith("zip") || fileName.endsWith("gz")) { + resourceSet.getLoadOptions().put(XMLResource.OPTION_ZIP, Boolean.TRUE); + } + resource = resourceSet.getResource(uri, true); + // gz is misleading, but supported for backwards compatibility + if (fileName.endsWith("zip") || fileName.endsWith("gz")) { + if (oldzip == null) { + resourceSet.getLoadOptions().remove(XMLResource.OPTION_ZIP); + } else { + resourceSet.getLoadOptions().put(XMLResource.OPTION_ZIP, oldzip); + } + } + } + } else { + ResourceSet resourceSet1; + unload = true; // Need to unload + resourceSet1 = createResourceSet(); + // gz is misleading, but supported for backwards compatibility + if (fileName.endsWith("zip") || fileName.endsWith("gz")) { + resourceSet1.getLoadOptions().put(XMLResource.OPTION_ZIP, Boolean.TRUE); + } + resource = resourceSet1.getResource(uri, true); + } + EObject e = resource.getContents().get(0); + if (unload) + resource.unload(); + return e; + } + + static public EObject file2ecore(String fileName, boolean unload, boolean useCommonRS) { + EList<EObject> l = file2ecores(fileName, unload, useCommonRS); + if (l.size() > 0) + return l.get(0); + return null; + } + + static public EList<EObject> file2ecores(String fileName, boolean unload, boolean useCommonRS) { + File file = new File(FileUtils.safeFileName(fileName)); + if (!file.exists()) { + throw new RuntimeException("File does not exists: " + fileName); + } + // URI uri = URI.createFileURI(file.getAbsolutePath()); + URI uri = URI.createURI("file:///" + file.getAbsolutePath().replace("\\", "/")); + Resource resource; + logger.debug("Loading " + uri); + EList<EObject> res = new BasicEList<EObject>(); + if (useCommonRS) { + init(); + synchronized (resourceSet) { + resource = resourceSet.createResource(uri); + } + } else { + ResourceSet resourceSet1 = createResourceSet(); + // unload = true; // Need to unload + resource = resourceSet1.createResource(uri); + } + Map<String, Object> options = new HashMap<String, Object>(); + // gz is misleading, but supported for backwards compatibility + if (fileName.endsWith("zip") || fileName.endsWith("gz")) { + options.put(XMLResource.OPTION_ZIP, Boolean.TRUE); + } + options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + try { + resource.load(options); + } catch (IOException e1) { + logger.error("I/O error loading " + safeFileName(fileName) + " : " + e1.getMessage()); + e1.printStackTrace(); + return res; + } catch (Exception e1) { + logger.error("Content error loading " + safeFileName(fileName) + " : " + e1.getMessage()); + e1.printStackTrace(); + return res; + } + res.addAll(resource.getContents()); + if (unload) + resource.unload(); + return res; + } + + static public void clearResourceSet() { + resourceSet = null; + } + + protected String validate(Resource resource, int i) { + for (EObject eObject : resource.getContents()) { + Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject); + if (diagnostic.getSeverity() != Diagnostic.OK) { + return printDiagnostic(diagnostic, ""); + } + } + return null; + } + + protected static String printDiagnostic(Diagnostic diagnostic, String indent) { + System.err.print(indent); + System.err.println(diagnostic.getMessage()); + + StringBuffer buf = new StringBuffer(); + buf.append(indent + diagnostic.getMessage() + "\n"); + for (Diagnostic child : diagnostic.getChildren()) { + buf.append(printDiagnostic(child, indent + " ") + "\n"); + } + return buf.toString(); + } + + static public void ecore2stream(EObject ecore, OutputStream out) { + init(); + Resource resource = resourceSet.createResource(URI.createURI("http:///foobar")); + resource.getContents().add(ecore); + try { + resource.save(out, null); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + static public BufferedReader filename2reader(String fileName, ErrorMap errors) { + InputStream s = filename2stream(fileName, errors); + if (s == null) + return null; + return new BufferedReader(new InputStreamReader(s)); + } + + public static InputStream filename2stream(String fileName, ErrorMap errors) { + InputStream res = null; + File aFile = new File(FileUtils.safeFileName(fileName)); + if (!aFile.canRead()) { + // try to see if a file with .gz extention exists. + aFile = new File(FileUtils.safeFileName(fileName + ".gz")); + if (aFile.canRead()) + return filename2stream(fileName + ".gz", errors); + if (errors != null) + errors.add("Unable to read", fileName); + return null; + } + try { + logger.debug("Reading " + fileName); + if (fileName.endsWith(".gz")) { + try { + res = new GZIPInputStream(new FileInputStream(FileUtils.safeFileName(fileName)), 524288); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else + res = new FileInputStream(aFile); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return res; + } + + public static ByteBuffer filename2buffer(String fileName, ErrorMap errors) { + ByteArrayOutputStream b = new ByteArrayOutputStream(); + InputStream in = filename2stream(fileName, errors); + if (in == null) { + return null; + } + byte[] buf = new byte[524288]; + int len; + while (true) { + try { + len = in.read(buf); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + errors.add("bad read", fileName); + break; + } + if (len == -1) { + break; + } + b.write(buf, 0, len); + } + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + errors.add("bad close", fileName); + } + return ByteBuffer.wrap(b.toByteArray(), 0, b.size()); + } + + public synchronized static InputStream cmd2stream(String cmd) { + Runtime runtime = Runtime.getRuntime(); + Process proc; + try { + proc = runtime.exec(cmd); + } catch (IOException e) { + e.printStackTrace(); + System.out.println("ERROR: " + e); + return null; + } + return proc.getInputStream(); + } + + public synchronized static BufferedReader cmd2reader(String cmd) { + return new BufferedReader(new InputStreamReader(cmd2stream(cmd))); + } + + public static OutputStreamWriter filename2writer(String fileName) { + return filename2writer(fileName, fileName.endsWith(".gz") || fileName.endsWith(".gz.tmp")); + } + + public static OutputStreamWriter filename2writer(String filename, boolean gzip) { + try { + File f = new File(FileUtils.safeFileName(filename)); + if (f.exists()) f.delete(); + String p = f.getParent(); + if (p != null) { + File d = new File(p); + d.mkdirs(); + } + if (gzip) { + OutputStream s = new GZIPOutputStream(new FileOutputStream(FileUtils.safeFileName(filename)), 524288); + return new OutputStreamWriter(s); + } else + return new FileWriter(FileUtils.safeFileName(filename)); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + private static void find(String dirName, String regex, List<String> res) { + File dir = new File(FileUtils.safeFileName(dirName)); + String[] children = dir.list(); + if (children == null) { + // Either dir does not exist or is not a directory + } else { + for (int i = 0; i < children.length; i++) { + // Get filename of file or directory + String ff = dirName + "/" + children[i]; + File f = new File(FileUtils.safeFileName(ff)); + if (f.isDirectory()) { + find(ff, regex, res); + } else { + if (children[i].matches(regex)) { + res.add(ff); + } + } + } + } + } + + public static List<String> find(String dir, String regexp) { + List<String> res = new ArrayList<String>(); + find(dir, regexp, res); + return res; + } + + public static void ecore2xmlfile(XMLProcessor x, EObject doc, String filename) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(FileUtils.safeFileName(filename)); + + ResourceSet resourceSet = new ResourceSetImpl(); + resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put("xml", new org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl()); + URI uri = URI.createURI(filename); + Resource resource = resourceSet.createResource(uri); + resource.getContents().add(doc); + Map<String, Object> options = new HashMap<String, Object>(); + options.put(XMLResource.OPTION_EXTENDED_META_DATA, x.getExtendedMetaData()); + x.save(fos, resource, options); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void mkdirForFile(String filename) { + File f = new File(FileUtils.safeFileName(filename)); + f.getParentFile().mkdirs(); + } + + public static boolean uptodate(String filename, String interval) { + File file = new File(FileUtils.safeFileName(filename)); + if (!file.exists()) + return false; + Date now = new Date(); + if (file.lastModified() + DateUtils.stringToDuration(interval) > now.getTime()) + return true; + return false; + } + + public static void touch(String filename) throws IOException { + File file = new File(FileUtils.safeFileName(filename)); + file.createNewFile(); + Date now = new Date(); + file.setLastModified(now.getTime()); + } + + public static void copyFile(String sourceFile, String destFile) throws IOException { + File from = new File(FileUtils.safeFileName(sourceFile)); + File to = new File(FileUtils.safeFileName(destFile)); + copyFile(from, to); + } + + public static void copyFile(File sourceFile, File destFile) throws IOException { + if (!destFile.exists()) { + destFile.createNewFile(); + } + + FileChannel source = null; + FileChannel destination = null; + try { + source = new FileInputStream(FileUtils.safeFile(sourceFile)).getChannel(); + destination = new FileOutputStream(FileUtils.safeFile(destFile)).getChannel(); + destination.transferFrom(source, 0, source.size()); + } finally { + if (source != null) { + source.close(); + } + if (destination != null) { + destination.close(); + } + } + } + + public static void copyDirectory(File sourceDir, File destDir) throws IOException { + logger.debug("copy: " + sourceDir.getAbsolutePath() + " " + destDir.getAbsolutePath()); + if (!destDir.exists()) { + destDir.mkdirs(); + } + for (File f : sourceDir.listFiles()) { + File dest = createSafeFile(destDir, f.getName()); + if (f.isDirectory()) { + copyDirectory(f, dest); + continue; + } + if (f.isFile()) { + copyFile(f, dest); + } + } + } + + public static void deleteDirectory(File dir) { + if (!dir.exists()) { + throw new RuntimeException("Directory does not exists: " + dir.getAbsolutePath()); + } + if (!dir.isDirectory()) { + throw new RuntimeException("Is not a directory: " + dir.getAbsolutePath()); + } + + logger.debug("deleting: " + dir.getAbsolutePath()); + for (File f : dir.listFiles()) { + if (f.isDirectory()) { + deleteDirectory(f); + continue; + } + if (f.isFile()) { + f.delete(); + } + } + dir.delete(); + } + + public static Object file2object(String filename) { + try { + InputStream in = filename2stream(filename, null); + if (in == null) + return null; + ObjectInputStream r = new ObjectInputStream(in); + Object o; + try { + o = r.readObject(); + } finally { + in.close(); + } + return o; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static void object2file(Object o, String filename) { + // TODO Auto-generated method stub + try { + String f = filename + ".tmp"; + File f1 = new File(safeFileName(f)); + File f2 = new File(safeFileName(filename)); + if (!f1.getParentFile().exists()) f1.getParentFile().mkdirs(); + ObjectOutputStream w = new ObjectOutputStream(new FileOutputStream(safeFileName(f))); + try { + w.writeObject(o); + w.flush(); + } finally { + w.close(); + } + f1.renameTo(f2); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void copyStream(InputStream in, OutputStream out) throws IOException { + copyStream(in, out, 524288); + } + + public static void copyStream(InputStream in, OutputStream out, int bufferSize) throws IOException { + byte[] buf = new byte[bufferSize]; + int len = 0; + while ((len = in.read(buf)) >= 0) { + out.write(buf, 0, len); + } + } + + public static void deleteEmptyDirectories(HashSet<File> dirs) { + HashSet<File> dirs1 = new HashSet<File>(); + for (File d : dirs) { + if (!d.exists() || !d.isDirectory()) continue; + if (d.listFiles().length > 0) continue; + if (!d.delete()) + logger.warn("unable to delete directory: " + d.getAbsolutePath()); + dirs1.add(d.getParentFile()); + } + if (dirs1.size() > 0) + deleteEmptyDirectories(dirs1); + } + + public static int cmd(String cmd, StringBuffer outBuf, StringBuffer errBuf) { + + Runtime runtime = Runtime.getRuntime(); + Process proc; + try { + proc = runtime.exec(cmd); + ByteArrayOutputStream o = new ByteArrayOutputStream(); + ByteArrayOutputStream e = new ByteArrayOutputStream(); + copyStream(proc.getInputStream(), o); + copyStream(proc.getErrorStream(), e); + int i = proc.waitFor(); + outBuf.append(o.toString()); + errBuf.append(e.toString()); + return i; + } catch (Exception e) { + e.printStackTrace(); + System.out.println("ERROR: " + e); + errBuf.append("ERROR: " + e + "\n"); + return -1; + } + } + + public static File createSafeFile(File dir, String fname) { + String fname2 = dir.getAbsolutePath() + "/" + fname; + return new File(safeFileName(fname2)); + } + + public static String safeFileName(String file) { + // creating file with safer creation. + if (file.contains("..")) + throw new RuntimeException("File name contain ..: " + file); + if (file.contains("\n")) + throw new RuntimeException("File name contain newline: " + file); + return file; + } + + private static File safeFile(File file) { + // creating file with safer creation. + if (file.getAbsolutePath().contains("..")) + throw new RuntimeException("File name contain ..: " + file.getAbsolutePath()); + return file; + } + + public static Thread copyStreamThread(final InputStream inputStream, final OutputStream outputStream) { + Thread t = new Thread() { + @Override + public void run() { + try { + copyStream(inputStream, outputStream); + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + t.start(); + return t; + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/IpUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/IpUtils.java new file mode 100644 index 0000000..62da451 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/IpUtils.java @@ -0,0 +1,217 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +public class IpUtils { + public static long toLong(String Ip) { + long res = 0; + try { + StringTokenizer tokens = new StringTokenizer(Ip, "."); + for (int i = 0; i < 4; i++) { + int t = Integer.parseInt(tokens.nextToken()); + if (t < 0 || t > 255) { + throw new RuntimeException("Bad IP: " + Ip); + } + res = 256 * res + t; + } + } catch (Exception e) { + throw new RuntimeException("Bad IP: " + Ip); + } + return res; + } + + public static int toInt(String Ip) { + long x = toLong(Ip); + // if (x<(1<<31)) return (int) x; + // TODO: does this really work?? + // System.out.println(Ip + " " + x); + return (int) x; + } + + public static String toString(int i) { + return ((i >> 24) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + (i & 0xFF); + } + + public static int mask2masklen(String string) { + // 255.255.255.252 -> 30 + if (!isIp(string)) { + return Integer.parseInt(string); + } + if (isIpv6(string)) { + throw new RuntimeException("IPv6 is not supported, just use mask length"); + } + StringTokenizer st = new StringTokenizer(string,"."); + int len = 0; + for (int j = 0; j < 4; j++) { + int i = Integer.parseInt(st.nextToken()); + for (int x = 0; x < 8; x++) { + if ((i >> x) % 2 == 1) { + len += 8 - x; + break; + } + + } + } + return len; + } + + private static int[] maskvals = {0,32,31,6,30,9,5,-1,29,16,8,2,4,21,-1,19,28, + 25,15,-1,7,10,1,17,3,22,20,26,-1,11,18,23,27,12,24,13,14}; + + public static int mask2masklen (int ip) { + // This works because 2 is a primitive root mod 37! + // The negation is because % is remainder, not modulus + int indx = -(ip % 37); + if (indx < 0) return -1; // caution for non-masks + return maskvals[indx]; + } + + public static String toPrefixString(int ip, int len) { + ip = (ip >> (32-len)) << (32-len); + return IpUtils.toString(ip) + "/" + len; + } + + private static Pattern ipv4Pattern = Pattern.compile("\\d*\\.\\d*\\.\\d*\\.\\d*"); + public static boolean isIpv4(String to) { + if (to.isEmpty()) return false; + char c = to.charAt(0); + if (c > '9' || c < '0') return false; + return ipv4Pattern.matcher(to).matches(); + } + private static Pattern ipv6Pattern = Pattern.compile("[0-9a-fA-F]*:[0-9a-fA-F]*:[0-9a-fA-F:]*"); + public static boolean isIpv6(String to) { + // bad heuristic but likely works most of the time. + return ipv6Pattern.matcher(to).matches(); + } + + public static boolean isIp(String to) { + return isIpv6(to) || isIpv4(to); + } + static int numBad = 0; + public static InetAddress toInetAddress(String string) { + if (!isIp(string)) return null; + try { + return InetAddress.getByName(string); + } catch (UnknownHostException e) { + if (numBad > 1000) { + e.printStackTrace(); + // We exit here since it is important not to do lots of DNS lookups + // We should validate that the string is a valid IP somehow. + System.exit(-3); + } + } + return null; + } + + public static String toPrefixString(InetAddress ip, int len) { + return mask(ip, len).getHostAddress() + "/" + len; + } + public static String toString(InetAddress ip) { + return ip.getHostAddress(); + } + public static InetAddress mask(InetAddress ip, int prefixMask) { + int oddBits = prefixMask % 8; + int nMaskBytes = prefixMask/8 + (oddBits == 0 ? 0 : 1); + byte[] mask = new byte[nMaskBytes]; +// byte[] addr = Arrays.copyOf(ip.getAddress(), ip.getAddress().length); +// To make this Java 5 compactible. + byte[] addr = new byte[ip.getAddress().length]; + for (int i =0 ; i < ip.getAddress().length ; i ++) + addr[i]=ip.getAddress()[i]; + Arrays.fill(mask, 0, oddBits == 0 ? mask.length : mask.length - 1, (byte)0xFF); + if (oddBits != 0) { + int finalByte = (1 << oddBits) - 1; + finalByte <<= 8-oddBits; + mask[mask.length - 1] = (byte) finalByte; + } + for (int i=0; i < mask.length; i++) { + addr[i] = (byte) (addr[i] & mask[i]); + } + for (int i=nMaskBytes; i < addr.length; i++) { + addr[i] = 0; + } + try { + return InetAddress.getByAddress(addr); + } catch (UnknownHostException e) { + e.printStackTrace(); + System.exit(2); + } + return null; + } + + public static int mask (int ip, int masklen) { + if (masklen == 0) return 0; + return ip & -(1 << (32-masklen)); + } + + public static String defaultPrefix(String tmVersion) { + if (tmVersion.equals("6")) { + return "::/0"; + } + return "0.0.0.0/0"; + } + + public static boolean containedIn(InetAddress ip, InetAddress ip2, int mask) { + return (mask(ip, mask).equals(mask(ip2, mask))); + } + + public static InetAddress anonymize(InetAddress ip) { + byte[] a = ip.getAddress(); + byte[] a2 = Arrays.copyOf(a, a.length); + a2[a.length-1] = (byte) (a2[a.length-1] ^ 17); + try { + return InetAddress.getByAddress(a2); + } catch (UnknownHostException e) { + e.printStackTrace(); + System.exit(3); + } + return null; + } + + public static boolean isIpv4(InetAddress ip) { + return ip.getAddress().length == 4; + } + + public static String firstIp(String prefix) { + String a[] = prefix.split("/"); + int ip = toInt(a[0]); + int len = Integer.parseInt(a[1]); + ip = mask(ip,len); + return toString(ip); + } + + public static String lastIp(String prefix) { + String a[] = prefix.split("/"); + int ip = toInt(a[0]); + int len = Integer.parseInt(a[1]); + if (len == 0) return "255.255.255.255"; + ip = mask(ip,len) + (1 << (32-len)) - 1; + return toString(ip); + } + +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/JsonUtilTest.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/JsonUtilTest.java new file mode 100644 index 0000000..0d46dc5 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/JsonUtilTest.java @@ -0,0 +1,47 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import junit.framework.TestCase; + +import org.json.JSONObject; + +public class JsonUtilTest extends TestCase { + public void test_getStringValue() { + JSONObject json= new JSONObject("{id:'dr.t','r':1.2,b:false,i:23,'metadata':{'empty':'foo'}}"); + assertEquals("dr.t", JsonUtils.getStringValue(json, "id")); + assertEquals("foo", JsonUtils.getStringValue(json, "metadata.empty")); + assertEquals("1.2", JsonUtils.getStringValue(json, "r")); + assertEquals("false", JsonUtils.getStringValue(json, "b")); + assertEquals("23", JsonUtils.getStringValue(json, "i")); + json = new JSONObject("{'id':'dr.test.INOUTOCTETS','feedname':'someone01','metadata':{'timestamp':1360031100000,'qname':'dr.test.INOUTOCTETS'}}"); + assertEquals("1360031100000", JsonUtils.getStringValue(json, "metadata.timestamp")); + } + public void test_quotes() { + JSONObject json= new JSONObject(); + json.put("aaa'\"bb", "a''\"b"); + String s = json.toString(); + JSONObject json2 = new JSONObject(s); + String s2 = json2.toString(); + assertEquals(s, s2); + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/JsonUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/JsonUtils.java new file mode 100644 index 0000000..ee899ed --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/JsonUtils.java @@ -0,0 +1,467 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import org.openecomp.ncomp.utils.PropertyUtil; +import org.openecomp.ncomp.utils.StringUtil; + +public class JsonUtils { + public static final Logger logger = Logger.getLogger(JsonUtils.class); + HashMap<String, List<String>> features = new HashMap<String, List<String>>(); + public static JsonUtils util = new JsonUtils(); + boolean useProxy = true; + + public JsonUtils() { + } + + public boolean isUseProxy() { + return useProxy; + } + + public void setUseProxy(boolean useProxy) { + this.useProxy = useProxy; + } + + public void addFeatures(String pfeature, String features1) { + List<String> l = new Vector<String>(); + for (String s : features1.split(":", -1)) { + l.add(s); + } + features.put(pfeature, l); + } + + @SuppressWarnings("unchecked") + private JSONObject ecore2json(EObject ecore, HashMap<EObject, String> map, String context) throws JSONException { + if (ecore == null) + return null; + JSONObject res = new JSONObject(); + if (useProxy && map.get(ecore) != null) { + res.put("__proxy", map.get(ecore)); + return res; + } + map.put(ecore, context); + if (context.length() > 0) { + context = context + "."; + } + ; + String cfeature = ecore.eContainingFeature() == null ? "none" : ecore.eContainingFeature().getName(); + res.put("_cfeature", cfeature); + List<String> show = features.get(cfeature); + for (EAttribute attr : ecore.eClass().getEAllAttributes()) { + if (show != null && show.size() > 0 && !show.contains(attr.getName())) + continue; + if (attr.getUpperBound() == -1 || attr.getUpperBound() > 1) { + JSONArray a = new JSONArray(); + List<Object> l = (List<Object>) ecore.eGet(attr); + for (Object o : l) { + if (attr.getEType().getInstanceTypeName().equals("java.lang.String")) { + a.put(o); + } else if (attr.getEType().getInstanceTypeName().equals("java.util.Date")) { + a.put(o); + } else if (attr.getEType().getInstanceTypeName().equals("int")) { + a.put(o); + } else if (attr.getEType().getInstanceTypeName().equals("long")) { + a.put(o); + } else if (attr.getEType().getInstanceTypeName().equals("boolean")) { + a.put(o); + } else if (attr.getEType().getInstanceTypeName().equals("double")) { + a.put(o); + } else { + a.put(o.toString()); + } + } + res.put(attr.getName(), a); + } else { + Object o = ecore.eGet(attr); + if (attr.getEType().getInstanceTypeName().equals("java.lang.String")) { + res.put(attr.getName(), o); + } else if (attr.getEType().getInstanceTypeName().equals("java.util.Date")) { + res.put(attr.getName(), o); + } else if (attr.getEType().getInstanceTypeName().equals("int")) { + res.put(attr.getName(), ecore.eGet(attr)); + } else if (attr.getEType().getInstanceTypeName().equals("long")) { + res.put(attr.getName(), ecore.eGet(attr)); + } else if (attr.getEType().getInstanceTypeName().equals("boolean")) { + res.put(attr.getName(), ecore.eGet(attr)); + } else if (attr.getEType().getInstanceTypeName().equals("double")) { + res.put(attr.getName(), o); + } else if (attr.getEType() instanceof org.eclipse.emf.ecore.EEnum) { + res.put(attr.getName(), o); + } else { + res.put(attr.getName(), "TODO: " + attr.getEType().getInstanceTypeName()); + } + } + } + for (EReference ref : ecore.eClass().getEAllReferences()) { + if (show != null && show.size() > 0 && !show.contains(ref.getName())) + continue; + if (ref.getUpperBound() == -1 || ref.getUpperBound() > 1) { + JSONArray a = new JSONArray(); + EList<EObject> l = (EList<EObject>) ecore.eGet(ref); + int i = 0; + for (EObject o : l) { + JSONObject json = ecore2json(o, map, context + ref.getName() + i); + a.put(json); + json.put("__index", i); + i++; + } + res.put(ref.getName(), a); + } else { + Object ee = ecore.eGet(ref); + res.put(ref.getName(), ecore2json((EObject) ee, map, context + ref.getName())); + } + } + return res; + } + + public JSONObject ecore2json(EObject ecore) { + try { + return ecore2json(ecore, new HashMap<EObject, String>(), ""); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + public String ecore2jsonString(EObject ecore, int indentFactor) { + try { + if (ecore == null) + return null; + return ecore2json(ecore, new HashMap<EObject, String>(), "").toString(indentFactor); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + public JSONArray ecores2json(EList<EObject> l) { + JSONArray res = new JSONArray(); + for (EObject e : l) { + res.put(ecore2json(e)); + } + return res; + } + + public static JSONObject merge(JSONObject md1, JSONObject md2) { + JSONObject o = new JSONObject(); + if (md1 == null) + return md2; + if (md2 == null) + return md1; + Iterator<String> i = md1.keys(); + while (i.hasNext()) { + String k = i.next(); + o.put(k, md1.get(k)); + } + i = md2.keys(); + while (i.hasNext()) { + String k = i.next(); + o.put(k, md2.get(k)); + } + return o; + } + + public static String getStringValue(JSONObject json, String name) { + String[] a = name.split("\\."); + return getStringValue(json, a, 0); + } + + private static String getStringValue(JSONObject json, String[] a, int i) { + if (i >= a.length) + return null; + Object o; + try { + o = json.get(a[i]); + } catch (JSONException e) { + return null; + } + if (i == a.length - 1) { + if (o instanceof String) { + String s = (String) o; + return s; + } + if (o instanceof Boolean || o instanceof Double || o instanceof Integer || o instanceof Long) { + return o.toString(); + } + return null; + } + if (o instanceof JSONObject) { + JSONObject json1 = (JSONObject) o; + return getStringValue(json1, a, i + 1); + } + return null; + } + + public static Object getValue(JSONObject json, String name) { + String[] a = name.split("\\."); + return getValue(json, a, 0); + } + + private static Object getValue(JSONObject json, String[] a, int i) { + if (i >= a.length) + return null; + Object o; + try { + o = json.get(a[i]); + } catch (JSONException e) { + return null; + } + if (i == a.length - 1) { + return o; + } + if (o instanceof JSONObject) { + JSONObject json1 = (JSONObject) o; + return getValue(json1, a, i + 1); + } + if (o instanceof JSONArray) { + JSONArray json1 = (JSONArray) o; + return getValue(json1, a, i + 1); + } + + return null; + } + + private static Object getValue(JSONArray json, String[] a, int i) { + if (i >= a.length) + return null; + Object o; + try { + o = json.get(Integer.parseInt(a[i])); + } catch (JSONException e) { + return null; + } + if (i == a.length - 1) { + return o; + } + if (o instanceof JSONObject) { + JSONObject json1 = (JSONObject) o; + return getValue(json1, a, i + 1); + } + return null; + } + + + public static JSONObject file2json(String file) throws IOException { + InputStream in = FileUtils.filename2stream(file, null); + if (in == null) + throw new RuntimeException("Unable to open: " + file); + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + try { + FileUtils.copyStream(in, buf); + } finally { + in.close(); + buf.close(); + } + return new JSONObject(buf.toString()); + } + + public static JSONObject file2json(String file, Properties props, String prefix) throws IOException { + InputStream in = FileUtils.filename2stream(file, null); + if (in == null) + throw new RuntimeException("Unable to open: " + file); + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + try { + FileUtils.copyStream(in, buf); + } finally { + in.close(); + buf.close(); + } + String s = buf.toString().replaceAll("##.*", ""); + try { + s = StringUtil.expandUsingProperties(s, props, prefix); + return new JSONObject(s); + } catch (JSONException e) { + logger.debug("bad JSON String" + s + " " + e); + throw e; + } + } + + public static HashMap<String, String> getStringValueMap(JSONObject v, String string) { + Object x = getValue(v, string); + if (!(x instanceof JSONObject)) { + throw new RuntimeException("Expected Json object value for key: " + string); + } + v = (JSONObject) x; + HashMap<String, String> res = new HashMap<String, String>(); + for (Iterator<String> i = v.keys(); i.hasNext();) { + String key = (String) i.next(); + Object o = v.get(key); + if (o instanceof String) { + String s = (String) o; + res.put(key, s); + } else + throw new RuntimeException("Expected string value for key: " + key); + } + return res; + } + + public static JSONObject stream2json(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + FileUtils.copyStream(in, out); + if (out.toString().length() == 0) return null; + String s = out.toString().replaceAll("##.*", ""); + try { + return new JSONObject(s); + } catch (JSONException e) { + logger.debug("bad JSON String" + s + " " + e); + throw e; + } + } + + public static String toStringLazy(Object oo, int indentFactor, int indent) throws JSONException { + int j; + if (oo instanceof JSONArray) { + JSONArray a = (JSONArray) oo; + return toStringLazy(a, indentFactor, indent); + } + if (! (oo instanceof JSONObject)) { + return JSONObject.valueToString(oo, indentFactor, indent); + } + JSONObject json = (JSONObject)oo; + int n = json.length(); + if (n == 0) { + return "{}"; + } + Iterator<String> keys = json.keys(); + StringBuffer sb = new StringBuffer("{"); + int newindent = indent + indentFactor; + Object o; + if (n == 1) { + o = keys.next(); + sb.append(o.toString()); + sb.append(": "); + sb.append(toStringLazy(json.get((String) o), indentFactor, indent)); + } else { + while (keys.hasNext()) { + o = keys.next(); + if (sb.length() > 1) { + sb.append(",\n"); + } else { + sb.append("\n"); + } + for (j = 0; j < newindent; j += 1) { + sb.append(' '); + } + sb.append(o.toString()); + sb.append(": "); + sb.append(toStringLazy(json.get((String) o), indentFactor, newindent)); + } + if (sb.length() > 1) { + sb.append('\n'); + for (j = 0; j < indent; j += 1) { + sb.append(' '); + } + } + } + sb.append('}'); + return sb.toString(); + } + public static String toStringLazy(JSONArray a, int indentFactor, int indent) throws JSONException { + int len = a.length(); + if (len == 0) { + return "[]"; + } + int i; + StringBuffer sb = new StringBuffer("["); + int newindent = indent + indentFactor; + if (len == 1) { + Object oo = a.get(0); + if (oo instanceof JSONArray) { + JSONArray aa = (JSONArray) oo; + sb.append(toStringLazy(aa, indentFactor, indent)); + } + else if (oo instanceof JSONObject) { + JSONObject ooo = (JSONObject) oo; + sb.append(toStringLazy(ooo, indentFactor, indent)); + } + else sb.append(JSONObject.valueToString(oo, + indentFactor, indent)); + } else { + sb.append('\n'); + for (i = 0; i < len; i += 1) { + if (i > 0) { + sb.append(",\n"); + } + for (int j = 0; j < newindent; j += 1) { + sb.append(' '); + } + sb.append(toStringLazy(a.get(i), + indentFactor, newindent)); + } + sb.append('\n'); + for (i = 0; i < indent; i += 1) { + sb.append(' '); + } + } + sb.append(']'); + return sb.toString(); + } + + public static JSONObject getJsonFromClasspath(String filename) { + JSONObject res = new JSONObject(); + if (filename == null) return res; + URL url = PropertyUtil.class.getClassLoader().getResource(filename); + InputStream inputStream = null; + try { + logger.info("Loading JSON" + url); + inputStream = PropertyUtil.class.getClassLoader().getResourceAsStream(filename); + if (inputStream == null) { + throw new FileNotFoundException("JSON file '" + filename + "' not found in the classpath"); + } + res = stream2json(inputStream); + } catch (Exception e) { + logger.warn("Bad JSON in file: " + url + " " + e); + e.printStackTrace(); + } finally { + if (inputStream != null) + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("unable to close stream",e); + } + } + return res; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/Pair.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/Pair.java new file mode 100644 index 0000000..fca39a2 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/Pair.java @@ -0,0 +1,62 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +public class Pair<T, U> { + private final T first; + private final U second; + private transient final int hash; + + public Pair(T f, U s) { + this.first = f; + this.second = s; + hash = (first == null ? 0 : first.hashCode() * 31) + (second == null ? 0 : second.hashCode()); + } + + public T getFirst() { + return first; + } + + public U getSecond() { + return second; + } + + @Override + public int hashCode() { + return hash; + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object oth) { + if (this == oth) { + return true; + } + if (oth == null || !(getClass().isInstance(oth))) { + return false; + } + Pair<T, U> other = getClass().cast(oth); + return (first == null ? other.first == null : first.equals(other.first)) + && (second == null ? other.second == null : second.equals(other.second)); + } + +}
\ No newline at end of file diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ProgessMonitor.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ProgessMonitor.java new file mode 100644 index 0000000..3634210 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ProgessMonitor.java @@ -0,0 +1,88 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +// TODO add error reporting + +import java.text.DecimalFormat; +import java.util.Date; + +public class ProgessMonitor { + private String name; + private int c = 0; + private int cThisInterval = 0; + private Date firstTime = new Date(); + private Date lastReportTime = new Date(); + int interval = 10000; + + public ProgessMonitor(String name1) { + name = name1; + } + + public synchronized void newRecord() { + c++; + cThisInterval++; + Date d1 = new Date(); + if (d1.getTime() - lastReportTime.getTime() > interval) { + report(); + } + } + + public void done() { + report(); + } + + private String milliseconds2string (long s) { + DecimalFormat twoPlaces = new DecimalFormat("00"); + long seconds = (s/1000) % 60; + long min = (s/1000/60) % 60; + long hour = (s/1000/60/60); + return hour + ":" + twoPlaces.format(min) + ":" + twoPlaces.format(seconds); + } + + void report() { + Date d1 = new Date(); + double total = c * 1000.0 / (d1.getTime() - firstTime.getTime()); + double total2 = cThisInterval * 1000.0 + / (d1.getTime() - lastReportTime.getTime()); + String unit = "sec"; + if (total<10) { + unit = "min"; + total *= 60; + total2 *= 60; + } + if (total<10) { + unit = "hour"; + total *= 60; + total2 *= 60; + } + System.out.println("Progress: " + + name + + " total records/" + unit + " " + (int) total + + " last interval " + (int) total2 + + " running time " + milliseconds2string(d1.getTime() - firstTime.getTime()) + + " total " + c + + String.format(" vsize=%.2fGB ", Runtime.getRuntime().totalMemory() / 1024.0 / 1024 / 1024)); + lastReportTime = d1; + cThisInterval = 0; + } +} diff --git a/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ServiceUtils.java b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ServiceUtils.java new file mode 100644 index 0000000..2140938 --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/openecomp/ncomp/webservice/utils/ServiceUtils.java @@ -0,0 +1,85 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ + +package org.openecomp.ncomp.webservice.utils; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +public class ServiceUtils { + private static int requestNumber = 0; + private static String requestString; + public static EObject BackendService(EPackage pp, EObject request, String command, String dir) { + if (dir == null) dir = getDirectory(pp); + String inputFile = dir + "/request"; + String outputFile = dir + "/response"; + EObject res = null; + try { + File dir1 = new File(dir); + dir1.mkdirs(); + if (request != null) { + FileUtils.ecore2file(pp, request, inputFile); + } + Date d1 = new Date(); + Process p = Runtime.getRuntime().exec( + command + " " + inputFile + " " + outputFile); + p.waitFor(); + p.destroy(); + Date d2 = new Date(); + System.err.println("Backend call: " + (d2.getTime() - d1.getTime()) + + " milliseconds"); + res = FileUtils.file2ecore(pp,outputFile,true,false); + } catch (Exception exception) { + System.err.println("SERVER ERROR: " + exception + " " + dir); + exception.printStackTrace(); + } + return res; + } + public static String getDirectory(EPackage pp) { + int n; + String prefix = pp.getName(); + Date now = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd",new Locale("UTC")); + String nowString = format.format(now); + if (!nowString.equals(requestString)) { + requestNumber = 0; + requestString = nowString; + } + String dir; + synchronized (requestString) { + while (true) { + n = requestNumber++; + dir = System.getProperty("user.dir")+"/" + prefix + "/requests/" + requestString + "/" + n; + File f = new File(dir); + if (!f.exists()) { + f.mkdirs(); + break; + } + } + } + return dir; + } +} |